Índice

 

Declaração <!DOCTYPE> HTML

Ao publicar um formulário não é recomendada a utilização de declarações:

<!DOCTYPE>, Ex: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

A utilização dessas pode impactar em algumas funcionalidades da definição de formulário ou do Workflow na utilização do navegador Microsoft® Internet Explorer ®.


FormController

 

O formController é o objeto que realiza a comunicação entre o formulário e a customização dos eventos. Esse objeto está disponível em cada um dos eventos de customização de
formulários através da variável form. A variável permite alterar os valores dos campos de um registro de formulário e também obter o estado de edição deles, por exemplo: se o
usuário está visualizando ou editando o registro de formulário. Veja a seguir os métodos disponíveis para a variável form:

MétodoDescrição
long getCompanyId()Retorna o ID da empresa
int getDocumentId()Retorna o ID do documento (registro de formulário)
int getVersion()Retorna a versão do documento (registro de formulário)
int getCardIndex()Retorna o ID do formulário
String getValue(String fieldName)Obtém o valor de um campo do formulário
void setValue(String fieldName, String fieldValue)Define o valor de um campo do formulário
boolean getEnabled(String fieldName)Verifica se um campo está habilitado
void setEnabled(String fieldName, boolean enabled)Define se um campo deve estar habilitado ou não
String getFormMode()

Obtém o modo de edição do formulário, podendo retornar os seguintes valores:
ADD: Criação do formulário

MOD: Formulário em edição

VIEW: Visualização do formulário

NONE: Não há comunicação com o formulário, por exemplo, ocorre no momento da validação dos campos do formulário onde este não está sendo apresentado.

void setHidePrintLink(boolean hide)Quando definido com o valor true, desabilita o botão de imprimir do formulário.
boolean isHidePrintLink()Verifica se o botão de imprimir está desabilitado.
Map<String, String> getChildrenFromTable(String tableName)Retorna um mapa contendo os nomes e valores dos campos filhos de uma tabela pai.
void setHideDeleteButton(boolean hide)Quando definido com o valor true, desabilita o botão de excluir registros filhos em um formulário com pai-filho.
boolean isHideDeleteButton()Verifica se a exclusão de registros filhos está desabilitada.
boolean getMobile()Verifica se o registro de formulário está sendo acessado através de um dispositivo mobile.
boolean isVisible(String fieldName)Verifica se um campo está marcado para ser visível
void setVisible(String fieldName, boolean visible)Define se um campo deve estar visível ou não
boolean isVisibleById(String id)Verifica se um item do html está marcado para ser visível
void setVisibleById(String id, boolean enabled)Define se um item do html deve estar visível ou não

Para o correto funcionamento do formulário no Fluig, todos os campos de formulário devem estar dentro da tag <form> no HTML principal ou identificar o formulário para cada campo, conforme padrão HTML. O Fluig utiliza internamente todos os campos de formulário que possuem a propriedade "name" para armazenamento das informações.

Quando o formulário é armazenado em tabelas do banco de dados, existem alguns termos que não podem ser utilizados no atributo "name", pois são palavras reservadas de alguns sistemas de banco de dados. Abaixo é apresentada uma lista de termos reservados:

"ABSOLUTE", "ACCESS", "ACCESSIBLE", "ACCOUNT", "ACTION", "ACTIVATE", "ADD",
"ADMIN", "ADVISE", "AFTER", "AGGREGATE", "ALIAS", "ALL", "ALLOCATE", "ALL_ROWS", "ALTER", "ANALYZE", "AND",
"ANY", "ARCHIVE", "ARCHIVELOG", "ARE", "ARRAY", "AS", "ASC", "ASENSITIVE", "ASSERTION", "AT", "AUDIT",
"AUTHENTICATED", "AUTHORIZATION", "AUTOEXTEND", "AUTOMATIC", "BACKUP", "BECOME", "BEFORE", "BEGIN",
"BETWEEN", "BFILE", "BIGINT", "BINARY", "BIT", "BITMAP", "BLOB", "BLOCK", "BODY", "BOOLEAN", "BOTH",
"BREADTH", "BREAK", "BROWSE", "BULK", "BY", "CACHE", "CACHE_INSTANCES", "CALL", "CANCEL", "CASCADE",
"CASCADED", "CASE", "CAST", "CATALOG", "CFILE", "CHAINED", "CHANGE", "CHAR", "CHARACTER", "CHAR_CS",
"CHECK", "CHECKPOINT", "CHOOSE", "CHUNK", "CLASS", "CLEAR", "CLOB", "CLOSE", "CLOSE_CACHED_OPEN_CURSORS",
"CLUSTER", "CLUSTERED", "COALESCE", "COLLATE", "COLLATION", "COLUMN", "COLUMNS", "COMMENT", "COMMIT",
"COMMITTED", "COMPATIBILITY", "COMPILE", "COMPLETE", "COMPLETION", "COMPOSITE_LIMIT", "COMPRESS",
"COMPUTE", "CONDITION", "CONNECT", "CONNECTION", "CONNECT_TIME", "CONSTRAINT", "CONSTRAINTS",
"CONSTRUCTOR", "CONTAINS", "CONTAINSTABLE", "CONTENTS", "CONTINUE", "CONTROLFILE", "CONVERT",
"CORRESPONDING", "COST", "CPU_PER_CALL", "CPU_PER_SESSION", "CREATE", "CROSS", "CUBE", "CURRENT",
"CURRENT_DATE", "CURRENT_PATH", "CURRENT_ROLE", "CURRENT_SCHEMA", "CURRENT_TIME", "CURRENT_TIMESTAMP",
"CURRENT_USER", "CURSOR", "CYCLE", "DANGLING", "DATA", "DATABASE", "DATABASES", "DATAFILE", "DATAFILES",
"DATAOBJNO", "DATE", "DAY", "DAY_HOUR", "DAY_MICROSECOND", "DAY_MINUTE", "DAY_SECOND", "DBA", "DBCC",
"DBHIGH", "DBLOW", "DBMAC", "DEALLOCATE", "DEBUG", "DEC", "DECIMAL", "DECLARE", "DEFAULT", "DEFERRABLE",
"DEFERRED", "DEGREE", "DELAYED", "DELETE", "DENY", "DEPTH", "DEREF", "DESC", "DESCRIBE", "DESCRIPTOR",
"DESTROY", "DESTRUCTOR", "DETERMINISTIC", "DIAGNOSTICS", "DICTIONARY", "DIRECTORY", "DISABLE",
"DISCONNECT", "DISK", "DISMOUNT", "DISTINCT", "DISTINCTROW", "DISTRIBUTED", "DIV", "DML", "DOMAIN",
"DOUBLE", "DROP", "DUAL", "DUMMY", "DUMP", "DYNAMIC", "EACH", "ELSE", "ELSEIF", "ENABLE", "ENCLOSED",
"END", "END-EXEC", "ENFORCE", "ENTRY", "EQUALS", "ERRLVL", "ESCAPE", "ESCAPED", "EVERY", "EXCEPT",
"EXCEPTION", "EXCEPTIONS", "EXCHANGE", "EXCLUDING", "EXCLUSIVE", "EXEC", "EXECUTE", "EXISTS", "EXIT",
"EXPIRE", "EXPLAIN", "EXTENT", "EXTENTS", "EXTERNAL", "EXTERNALLY", "FAILED_LOGIN_ATTEMPTS", "FALSE",
"FAST", "FETCH", "FILE", "FILLFACTOR", "FIRST", "FIRST_ROWS", "FLAGGER", "FLOAT", "FLOAT4", "FLOAT8",
"FLOB", "FLUSH", "FOR", "FORCE", "FOREIGN", "FOUND", "FREE", "FREELIST", "FREELISTS", "FREETEXT",
"FREETEXTTABLE", "FROM", "FULL", "FULLTEXT", "FUNCTION", "GENERAL", "GET", "GLOBAL", "GLOBALLY",
"GLOBAL_NAME", "GO", "GOTO", "GRANT", "GROUP", "GROUPING", "GROUPS", "HASH", "HASHKEYS", "HAVING",
"HEADER", "HEAP", "HIGH_PRIORITY", "HOLDLOCK", "HOST", "HOUR", "HOUR_MICROSECOND", "HOUR_MINUTE",
"HOUR_SECOND", "ID", "IDENTIFIED", "IDENTITY", "IDENTITYCOL", "IDENTITY_INSERT", "IDGENERATORS",
"IDLE_TIME", "IF", "IGNORE", "IGNORE_SERVER_IDS", "IMMEDIATE", "IN", "INCLUDING", "INCREMENT", "INDEX",
"INDEXED", "INDEXES", "INDICATOR", "IND_PARTITION", "INFILE", "INITIAL", "INITIALIZE", "INITIALLY",
"INITRANS", "INNER", "INOUT", "INPUT", "INSENSITIVE", "INSERT", "INSTANCE", "INSTANCES", "INSTEAD", "INT",
"INT1", "INT2", "INT3", "INT4", "INT8", "INTEGER", "INTERMEDIATE", "INTERSECT", "INTERVAL", "INTO", "IS",
"ISOLATION", "ISOLATION_LEVEL", "ITERATE", "JOIN", "KEEP", "KEY", "KEYS", "KILL", "LABEL", "LANGUAGE",
"LARGE", "LAST", "LATERAL", "LAYER", "LEADING", "LEAVE", "LEFT", "LESS", "LEVEL", "LIBRARY", "LIKE",
"LIMIT", "LINEAR", "LINENO", "LINES", "LINK", "LIST", "LOAD", "LOB", "LOCAL", "LOCALTIME",
"LOCALTIMESTAMP", "LOCATOR", "LOCK", "LOCKED", "LOG", "LOGFILE", "LOGGING", "LOGICAL_READS_PER_CALL",
"LOGICAL_READS_PER_SESSION", "LONG", "LONGBLOB", "LONGTEXT", "LOOP", "LOW_PRIORITY", "MANAGE", "MAP",
"MASTER", "MASTER_HEARTBEAT_PERIOD", "MASTER_SSL_VERIFY_SERVER_CERT", "MATCH", "MAX", "MAXARCHLOGS",
"MAXDATAFILES", "MAXEXTENTS", "MAXINSTANCES", "MAXLOGFILES", "MAXLOGHISTORY", "MAXLOGMEMBERS", "MAXSIZE",
"MAXTRANS", "MAXVALUE", "MEDIUMBLOB", "MEDIUMINT", "MEDIUMTEXT", "MEMBER", "MIDDLEINT", "MIN",
"MINEXTENTS", "MINIMUM", "MINUS", "MINUTE", "MINUTE_MICROSECOND", "MINUTE_SECOND", "MINVALUE", "MLSLABEL",
"MLS_LABEL_FORMAT", "MOD", "MODE", "MODIFIES", "MODIFY", "MODULE", "MONTH", "MOUNT", "MOVE",
"MTS_DISPATCHERS", "MULTISET", "NAMES", "NATIONAL", "NATURAL", "NCHAR", "NCHAR_CS", "NCLOB", "NEEDED",
"NESTED", "NETWORK", "NEW", "NEXT", "NO", "NOARCHIVELOG", "NOAUDIT", "NOCACHE", "NOCHECK", "NOCOMPRESS",
"NOCYCLE", "NOFORCE", "NOLOGGING", "NOMAXVALUE", "NOMINVALUE", "NONCLUSTERED", "NONE", "NOORDER",
"NOOVERRIDE", "NOPARALLEL", "NOREVERSE", "NORMAL", "NOSORT", "NOT", "NOTHING", "NOWAIT",
"NO_WRITE_TO_BINLOG", "NULL", "NULLIF", "NUMBER", "NUMERIC", "NVARCHAR2", "OBJECT", "OBJNO", "OBJNO_REUSE",
"OF", "OFF", "OFFLINE", "OFFSETS", "OID", "OIDINDEX", "OLD", "ON", "ONLINE", "ONLY", "OPCODE", "OPEN",
"OPENDATASOURCE", "OPENQUERY", "OPENROWSET", "OPENXML", "OPERATION", "OPTIMAL", "OPTIMIZE",
"OPTIMIZER_GOAL", "OPTION", "OPTIONALLY", "OR", "ORDER", "ORDINALITY", "ORGANIZATION", "OSLABEL", "OUT",
"OUTER", "OUTFILE", "OUTPUT", "OVER", "OVERFLOW", "OWN", "PACKAGE", "PAD", "PARALLEL", "PARAMETER",
"PARAMETERS", "PARTIAL", "PARTITION", "PASSWORD", "PASSWORD_GRACE_TIME", "PASSWORD_LIFE_TIME",
"PASSWORD_LOCK_TIME", "PASSWORD_REUSE_MAX", "PASSWORD_REUSE_TIME", "PASSWORD_VERIFY_FUNCTION", "PATH",
"PCTFREE", "PCTINCREASE", "PCTTHRESHOLD", "PCTUSED", "PCTVERSION", "PERCENT", "PERMANENT", "PLAN",
"PLSQL_DEBUG", "POSTFIX", "POST_TRANSACTION", "PRECISION", "PREFIX", "PREORDER", "PREPARE", "PRESERVE",
"PRIMARY", "PRINT", "PRIOR", "PRIVATE", "PRIVATE_SGA", "PRIVILEGE", "PRIVILEGES", "PROC", "PROCEDURE",
"PROFILE", "PUBLIC", "PURGE", "QUEUE", "QUOTA", "RAISERROR", "RANGE", "RAW", "RBA", "READ", "READS",
"READTEXT", "READUP", "READ_WRITE", "REAL", "REBUILD", "RECONFIGURE", "RECOVER", "RECOVERABLE", "RECOVERY",
"RECURSIVE", "REF", "REFERENCES", "REFERENCING", "REFRESH", "REGEXP", "RELATIVE", "RELEASE", "RENAME",
"REPEAT", "REPLACE", "REPLICATION", "REQUIRE", "RESET", "RESETLOGS", "RESIGNAL", "RESIZE", "RESOURCE",
"RESTORE", "RESTRICT", "RESTRICTED", "RESULT", "RETURN", "RETURNING", "RETURNS", "REUSE", "REVERSE",
"REVOKE", "RIGHT", "RLIKE", "ROLE", "ROLES", "ROLLBACK", "ROLLUP", "ROUTINE", "ROW", "ROWCOUNT",
"ROWGUIDCOL", "ROWID", "ROWNUM", "ROWS", "RULE", "SAMPLE", "SAVE", "SAVEPOINT", "SB4", "SCAN_INSTANCES",
"SCHEMA", "SCHEMAS", "SCN", "SCOPE", "SCROLL", "SD_ALL", "SD_INHIBIT", "SD_SHOW", "SEARCH", "SECOND",
"SECOND_MICROSECOND", "SECTION", "SEGMENT", "SEG_BLOCK", "SEG_FILE", "SELECT", "SENSITIVE", "SEPARATOR",
"SEQUENCE", "SERIALIZABLE", "SESSION", "SESSIONS_PER_USER", "SESSION_CACHED_CURSORS", "SESSION_USER",
"SET", "SETS", "SETUSER", "SHARE", "SHARED", "SHARED_POOL", "SHOW", "SHRINK", "SHUTDOWN", "SIGNAL", "SIZE",
"SKIP", "SKIP_UNUSABLE_INDEXES", "SLOW", "SMALLINT", "SNAPSHOT", "SOME", "SORT", "SPACE", "SPATIAL",
"SPECIFIC", "SPECIFICATION", "SPECIFICTYPE", "SPLIT", "SQL", "SQLEXCEPTION", "SQLSTATE", "SQLWARNING",
"SQL_BIG_RESULT", "SQL_CALC_FOUND_ROWS", "SQL_SMALL_RESULT", "SQL_TRACE", "SSL", "STANDBY", "START",
"STARTING", "STATE", "STATEMENT", "STATEMENT_ID", "STATIC", "STATISTICS", "STOP", "STORAGE", "STORE",
"STRAIGHT_JOIN", "STRUCTURE", "SUCCESSFUL", "SWITCH", "SYNONYM", "SYSDATE", "SYSDBA", "SYSOPER", "SYSTEM",
"SYSTEM_USER", "SYS_OP_ENFORCE_NOT_NULL$", "SYS_OP_NTCIMG$", "TABLE", "TABLES", "TABLESPACE",
"TABLESPACE_NO", "TABNO", "TEMPORARY", "TERMINATE", "TERMINATED", "TEXTSIZE", "THAN", "THE", "THEN",
"THREAD", "TIME", "TIMESTAMP", "TIMEZONE_HOUR", "TIMEZONE_MINUTE", "TINYBLOB", "TINYINT", "TINYTEXT", "TO",
"TOP", "TOPLEVEL", "TRACE", "TRACING", "TRAILING", "TRAN", "TRANSACTION", "TRANSITIONAL", "TRANSLATION",
"TREAT", "TRIGGER", "TRIGGERS", "TRUE", "TRUNCATE", "TSEQUAL", "TX", "TYPE", "UB2", "UBA", "UID",
"UNARCHIVED", "UNDER", "UNDO", "UNION", "UNIQUE", "UNKNOWN", "UNLIMITED", "UNLOCK", "UNNEST",
"UNRECOVERABLE", "UNSIGNED", "UNTIL", "UNUSABLE", "UNUSED", "UPDATABLE", "UPDATE", "UPDATETEXT", "USAGE",
"USE", "USER", "USING", "UTC_DATE", "UTC_TIME", "UTC_TIMESTAMP", "VALIDATE", "VALIDATION", "VALUE",
"VALUES", "VARBINARY", "VARCHAR", "VARCHAR2", "VARCHARACTER", "VARIABLE", "VARYING", "VIEW", "WAITFOR",
"WHEN", "WHENEVER", "WHERE", "WHILE", "WITH", "WITHOUT", "WORK", "WRITE", "WRITEDOWN", "WRITETEXT",
"WRITEUP", "XID", "XOR", "YEAR", "YEAR_MONTH", "ZEROFILL", "ZONE"


 

Customização de Formulários

A customização de definição de formulários é realizada pela criação de scripts na linguagem JavaScript. O código de implementação de cada script é armazenado em banco de dados e dispensa o uso de quaisquer outros arquivos, como por exemplo, “plugin.p”.

Os eventos de customização para a definição de formulários são criados a partir do Fluig Studio. Para publicar um formulário siga os passos conforme exemplo a seguir:

 

  • Para a criação de uma definição de formulário, na visão Explorador de pacotes deve-se acessar a pasta forms do projeto Fluig, clicar com o botão direito e no menu acessar Novo > Definição de Formulário

Figura 1 - Nova Definição de Formulário.

 

 

  • Na tela de criação de definição de formulário, basta preencher o nome desejado e clicar em concluir.

Figura 2 - Nova Definição de Formulário.


 

  • Ao concluir, um pacote referente à definição de formulário é criado na pasta forms e o editor de formulário fica disponível para edição.

Figura 3 - Nova Definição de Formulário.


 

  • A partir do editor, todo o conteúdo HTML é desenvolvido. No exemplo um formulário simples de cadastro foi desenvolvido.

Figura 4 - Nova Definição de Formulário.

 

 

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 deve-se acessar a pasta forms do projeto Fluig, clicar com o botão direito e no menu acessar Novo > Outras

Figura 5 - Criação de script evento da definição de formulário.

 

 

  • Selecione a opção Script Evento de definição de formulário e clique no botão Avançar.

Figura 6 - Criação de script evento da definição de formulário.


 

  • Nesta tela é necessário informar os campos pertinentes ao evento que se deseja adicionar e clicar no botão Concluir.

Figura 7 - Criação de script evento da definição de formulário.


 

  • No exemplo selecionamos o evento displayFields, e o relacionamos a definição de formulário form_exemplo_fluig.

Figura 8 - Criação de script evento da definição de formulário.

 

 

  • Ao concluir a estrutura principal do método estará disponível no editor.

Figura 9 - Criação de script evento da definição de formulário.

 

 

  • O evento utilizado como exemplo - validateForm, valida o preenchimento dos campos solicitação e usuário.

    O objeto formController, foi utilizado para verificar o valor dos campos, através da sintaxe ‘form.getValue(“fieldname”)’.

    Ao exportar a definição de formulário os eventos pertinentes a estes também serão exportados para o servidor Fluig.

     

Figura 10 - Criação de script evento da definição de formulário.

 

 

Todos os eventos da definição de formulário recebem a referência ao formulário. Através dessa referência é possível acessar os campos do formulário, acessar/definir o valor de um campo e acessar/definir o estado de apresentação do campo. Os detalhes de cada evento são apresentados nas próximas seções deste documento.

O Fluig é possível utilizar log de execução nos eventos de customização. Através da variável global log é possível obter o feedback da execução de cada evento. Existem quatro níveis de log, são eles:

A apresentação de cada um dos tipos de log está condicionada a configuração do servidor de aplicação. Por exemplo, no JBoss®, por padrão, as mensagens do tipo info e warn são apresentadas no console do servidor e as do tipo debug, error são apresentadas no arquivo de log. Abaixo um exemplo de uso do log em script:

log.info(“Testando o log info”);

Teríamos no console do servidor a mensagem “Testando o log info”.

É possível saber o estado de edição de um formulário através da variável form passada como parâmetro para os eventos da definição formulário. Para acessar o estado de edição:

form.getFormMode()

A chamada a função form.getFormMode() vai retornar uma string com o modo de edição do formulário. Existem os seguintes valores para o modo de edição do formulário:

A seguir serão detalhados os eventos disponíveis para a customização de uma definição de formulário no Fluig.

 

AfterProcessing

É o último evento a ser disparado para o fichário. O evento recebe como parâmetro uma referência ao formulário da definição de formulário.

Exemplo:

function afterProcessing(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.

 

AfterSaveNew

Esse evento é disparado após a criação de um novo formulário. O evento recebe como parâmetro uma referência ao formulário da definição de formulário.

Para obter o valor de um determinado campo do formulário:

 form.getValue("nome-do-campo")

Exemplo:

 function afterSaveNew(form) {
  log.info("Colaborador de abertura: " + form.getValue("RNC_colab_abertura"));
}

A consulta aos campos do formulário é case insensitve. No exemplo acima, poderíamos obter o valor do campo usando rnc_colab_abertura.

 

BeforeProcessing

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 uma referência ao formulário da definição de formulário.

Exemplo:

function beforeProcessing(form){
}

No contexto deste evento a variável form pode ser usada somente para consulta aos campos da definição de fromulário, seus valores e estado de apresentação.

 

DisplayFields

Esse evento é disparado no momento em que os objetos do formulário são apresentados. O evento recebe como parâmetro uma referência ao formulário da definição de formulário e a referência para saída de apresentação do formulário.

Nesse evento é possível alterar os valores a serem apresentados no campo do formulário. Para isto basta usar o seguinte procedimento:

form.setValue(“nome-do-campo”, “valor”);

Exemplo:

 function displayFields(form, customHTML) {
   if ( form.getFormMode() == “MOD” ) {
     form.setValue('RNC_colab_abertura', new java.lang.Integer(1));
   }
}

 

Ainda no evento DisplayFields é possível utilizar três métodos de forma independente ou conjunta para alterar a forma de como é apresentada a renderização do formulário, eliminar linhas de um fichário filho e ocultar os botões “Imprimir” e “Imprimir em nova Janela”.

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 fichá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.

 

 

Exemplo de visualização sem a utilização dos métodos:

Figura 11 - Exemplo sem utilização dos métodos.


Exemplo de utilização dos métodos setShowDisabledFields e setHidePrintLink:

function displayFields(form, customHTML) { 
   form.setShowDisabledFields(true);
   form.setHidePrintLink(true);
}


Figura 12 - Exemplo de utilização dos métodos.

 

 

Exemplo de visualização sem a utilização do método setHideDeleteButton:

Figura 13 - Exemplo sem utilização do método.

 

Exemplo de utilização do método setHideDeleteButton:

function displayFields(form, customHTML) { 
   form.setHideDeleteButton(false);
}

Figura 14 - Exemplo de utilização dos métodos.


Exemplo de utilização dos métodos setVisible e setVisibleById:

 

function displayFields(form, customHTML) { 
   form.setVisible("campoA", false);
   form.setVisibleById("linha___1", false);
}

 

Formulário funcional com exemplos de utilização de setVisiblesetVisibleById, setHideDeleteButton e setHidePrintLink:


<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>


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
	}
}

 


 

É importante destacar que este evento é o único que permite a alteração dos valores a serem apresentados nos campos formulário antes da renderização deste.

Abaixo um exemplo para usar a saída de apresentação do formulário:

if(form.getFormMode() != "VIEW")  {
    customHTML.append("<script>");
    customHTML.append("function MostraEscondeBtn_zoom()");
    customHTML.append("{");
    customHTML.append("document.getElementById(\'zoomUsuario\').className = \'show\';"); 
    customHTML.append("document.getElementById(\'zoomModulo\').className = \'show\';");
    customHTML.append("}"); 
    customHTML.append("</script>");
}


EnableFields

Esse evento é disparado no momento em que os objetos do formulário são habilitados, permitindo desabilitar alguns campos, caso haja a necessidade. O evento recebe como parâmetro uma referência ao formulário da definição de formulário.

Para habilitar ou desabilitar um campo do formulário o seguinte procedimento deve ser executado:

 form.setEnabled("nome-do-campo",true/false)

Onde “true” habilita o campo e “false” desabilita o campo.

Exemplo:

function enableFields(form) { 
    if ( form.getFormMode() != 'ADD' ){    
		form.setEnabled("rnc_area",false);
        form. setEnabled("rnc_tipo_ocorrencia",false);
    }
}

É importante destacar que o evento ocorre no momento da renderização do formulário e é o único que permite alterar o estado de apresentação dos campos do formulário.

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:

document.forms['nomeForm'].nomeCampo.setAttribute('readonly',true);

 

InputFields

Esse evento é disparado no momento em que os dados do formulário são passados para a BO responsável por formulário do Fluig. O evento recebe como parâmetro uma referência ao formulário da definição de formulário. Exemplo:

function inputFields(form){
}

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 são salvas com padrão americano (yyyy-mm-dd), enquanto as datas nos demais navegadores são salvas com 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.

 

function inputFields(form) {
	if (form.getValue("NOME_DO_CAMPO_DATA").match("^[0-3]?[0-9]/[0-3]?[0-9]/(?:[0-9]{2})?[0-9]{2}$")) {
		var split = form.getValue("NOME_DO_CAMPO_DATA").split('/');
		form.setValue("NOME_DO_CAMPO_DATA", split[2] + '-' + split[1] + '-' + split[0]);
	}
}

 

SetEnable

Esse evento pode ser executado em diferentes eventos das definições de formulário. Este evento não é implementado automaticamente na customização da definição de formulário.

Exemplo:

function setEnable() {
  log.info(“Teste de chamada de função”);
}
 
function displayFields(form, customHTML) {
  setEnable();
}

 

ValidateForm

Esse evento é executado antes da gravação dos dados do formulário no banco de dados. O evento recebe como parâmetro uma referência ao formulário da definição de formulário. Em caso de erros de validação dos dados do formulário esse evento irá retornar uma mensagem de erro.

Exemplo:

function validateForm(form) {
   if (form.getValue('RNC_colab_abertura') == null){
     throw "O colaborador de abertura não foi informado";
   }   
}  

 

Controles visuais

Neste capítulo será demonstrado como interagir com alguns tipos de controles do formulário que possuem características especiais, como por exemplo, o preenchimento do conteúdo de um ComboBox através da utilização de Datasets.

 

O Fluig, por padrão realiza a importação da biblioteca JavaScript jQuery em todos os formulários, exceto nos casos onde o formulário já a realize. Nestes casos o Fluig identificará que o jQuery já esta definido e não realizará a importação novamente. Caso o formulário utilize outra biblioteca que possa entrar em conflito com o jQuery,  será necessário definir no formulário a variável javascript fluigjQuery, com valor false, que o Fluig deixará de fazer tal importação, porem algumas outras funcionalidades como a mascara de campos do Fluig, também serão desabilitadas.

 

Máscara de Campos

Muitos campos em um formulário possuem uma formatação específica para o seu conteúdo, como  datas, CEP, CPF entre outros. 

Para auxiliar o desenvolvedor de formulários, o Fluig permite habilitar mascarás por campo, bastando informar o atributo "mask" e a máscara desejada aos objetos input do tipo text.

<input name="cep" type="text" mask="00000-000">


Para elaborar a máscara é possível utilizar:

CódigoDescrição
0Somente Números.
9Somente números mais opcional.
#Somente números mais recursivo.
ANúmeros ou letras.
SSomente letras entre A-Z e a-z.
                     
                     Data: "00/00/0000"
                  Horário: "00:00:00"
              Data e Hora: "00/00/0000 00:00:00"
                      CEP: "00000-000"
                 Telefone: "0000-0000"
            Telefone(ddd): "(00) 0000-0000"
Telefone(ddd + 9ºdígitos): "(00) 90000-0000"
           Placa de carro: "SSS 0000"
                      CPF: "000.000.000-00"
                     CNPJ: "00.000.000/0000-00"
                       IP: "099.099.099.099"
              porcentagem: "#00.000,00%"
				    Valor: "#00.000.000.000.000,00"
O Fluig mobile não suporta o atributo mask.
Caso a importação da biblioteca jQuery esteja desabilitada através da variável fluigjQuery, a funcionalidade de máscaras também estará desabilitada.

 

ComboBox

Geralmente é necessário popular um ComboBox de um formulário com um determinado grupo de valores.

No Fluig isto é possível através da utilização de Datasets. Os Datasets são serviços de dados padrão disponibilizados pelo Fluig, como por exemplo, o serviço de “Volumes” do produto.

Para habilitar o Dataset no ComboBox basta usar a seguinte construção:

<select name="RNC_volume" id="RNC_volume" dataset="nome-dataset" datasetkey="chave" datasetvalue="valor" addBlankLine=”false”></select>

Onde:

Exemplo:

<select name="RNC_volume" id="RNC_volume" dataset="destinationVolume" datasetkey="volumeID" datasetvalue="volumeDescription"></select>

No exemplo acima estamos listando em um ComboBox todas os Volumes cadastradas no Fluig.

 

Caso seja necessária a ordenação dos dados provindos de um dataset interno, indicamos a criação de um dataset customizado que execute o interno e ordene os dados, antes de alimentar o componente combobox.

Para utilizar um ComboBox com somente uma opção não deve ser utilizado caracteres especiais e espaço no value da tag option.

Exemplos:

<select>
  <option value="te">Teste</option>
</select>

 

<select>
  <option value="te te te">Teste</option>
</select>

 

Zoom

Permite a consulta de entidades e outros formulário criados no Fluig para seleção de dados pelo usuário.

Para utilizar este componente basta inserir um campo de texto com alguns parâmetros específicos .
<input 
	type="zoom"  
	name="colleague_zoom1"
	data-zoom="{
		'datasetId':'colleague',
		'fields':[
			{
				'field':'colleagueId', 
				'label':'ID'
			},{
				'field':'colleagueName', 
				'label':'Nome', 
				'standard':'true', 
				'search':'true'
			}
		]
	}" />

Onde:

 

ATENÇÃO: Este parâmetro só é válido para datasets internos. Datasets customizados não permitem a utilização de filtros.

 

function setSelectedZoomItem(selectedItem) {               
}

Onde selectItem é o registro selecionado pelo usuário na tela de zoom.



selectedItem["fieldName"]

Onde fieldName é o nome do campo de retorno que foi definido na chamada de zoom.Para obter o registroo componente de Zoom do fluig foi desenvolvido para permitir que o recurso de zoom fosse utilizado em definições de formulários.

 

Para que seja possível visualizar e resgatar informações dos campos “metadatas” do formulário, é necessário utilizar a seguinte nomenclatura:

metadata_id

Retorna o código do registro de formulário

medatata_version

Retorna a versão do registro de formulário

metadata_parent_id

Retorna o código da pasta Pai

metadata_card_index_id

Retorna o código do formulário

metadata_card_index_version

Retorna a versão do formulário

metadata_active

Versão ativa

A utilização da PK nos filtros ao utilizar dataset de Grupo, Papel ou Colaborador é opcional, porém o mesmo valor utilizado definição do zoom deve ser utilizado para a obtenção do valor selecionado, conforme exemplo abaixo.

 

Visualização e resgate destes valores

Para utilizar filtros a chamada é similar ao de dataFields.

window.open("/webdesk/zoom.jsp?datasetId=preCad&dataFields=codigo, Código, descricao, Descrição&resultFields=descricao&type=precad&filterValues=metadata_active, false","zoom" , "status, scrollbars=no, width=600, height=350, top=0, left=0");

Neste exemplo, o zoom irá retornar somente os registros de formulários inativos.

 

A antiga técnica para zoom ainda é suportada pela plataforma. Porém, recomendamos a utilização da técnica descrita acima que está de acordo com os padrões do fluig Style Guide e permite maior fluidez utilizando o componente.

 

Zoom Externo

Em situações aonde os dados dos elementos externos ao Fluig são muito volumosos é recomendada a construção de uma aplicação externa ao Fluig que fará o papel de zoom para o usuário. Abaixo será descrita uma técnica JavaScript aonde será possível chamar uma aplicação externa e a mesma poderá devolver o dado solicitado pelo usuário para um campo do formulário do Fluig.

O primeiro passo para implementação dessa técnica é criar uma lógica em JavaScript que irá abrir uma nova janela chamando a aplicação externa que irá se comportar como zoom para o formulário. Vamos utilizar e explanar o comando window.open neste exemplo:

Window.open(URL Aplicação Externa, Nome da Janela que será aberta, comandos adicionais)

Onde:

Devido a uma restrição dos navegadores a url do programa de zoom externo ao Fluig deverá estar no mesmo domínio em que o Fluig se encontra. Caso contrário não será possível atribuir ao campo do formulário o valor escolhido para o zoom. Este problema ocorrerá por que os navegadores proíbem a pratica de codificação JavaScript cross-domain.

 

O código abaixo irá programar um formulário do Fluig contendo um campo e um botão lateral que irá invocar a janela da aplicação externa.

<form name=”FornecedorForm”>
  Código do Fornecedor:
  <input name=”cod_fornec” size=’10” value=”” type=”text”>
  <input value=”lista” onClick=”mostraLista()” type=”button”>
</form>

<script language=”JavaScript”>
   Function mostraLista() {
     Window.open(“fornecedores.html”, “list”,”width=230,height=230”);
   }
</script>       

 

O segundo passo é programar dentro da aplicação externa uma função JavaScript que devolva para o campo do formulário o valor escolhido para o usuário na aplicação externa. Essa aplicação externa poderá ser desenvolvida em qualquer tecnologia de desenvolvimento web existente no mercado de que a mesma possa realizar a execução de scripts JavaScript no lado do cliente. Segue exemplo de uma função JavaScript que passa o valor para o campo do formulário:

<script language=”JavaScript”>
   function escolha(valor) {
       // A linha abaixo testa se a janela do formulário do fluig que abriu a janela de zoom ainda está aberta
       if (window.opener && !window.opener.close) {
              // seta o valor passando para o campo
              window.opener.document.(id do form no formulário fluig).(nome do campo).value = valor;
       }
       // Fecha a janela da aplicação zoom
       window.close();
   }
</script>

Onde:

 

O exemplo a seguir irá programar um exemplo de zoom externo feito inteiramente em HTML com dados estáticos apenas para ilustração. Os dados de zoom podem provir de qualquer fonte seja ela interna ou externa ao Fluig.

<html>
  <head>
  <title>Lista de fornecedores</title> 


<script language="JavaScript"> 
function escolha(valor) { 
  // Teste de validade do Opener 
  if (window.opener && !window.opener.closed) { 
      // gravando o valor do campo cod_fornec 
      window.opener.document.forms[0].cod_fornec.value = valor; 
  } 
   window.close(); 
} 
</script>
 
  </head>
  <body>   

  <!-- Os dados abaixo estão fixos mas poderiam ser montados a partir de qualquer origem. --> 

  <table border="1" cellpadding="5" cellspacing="0"> 
  <tbody><tr bgcolor="#cccccc"><td colspan="2"><b>Exemplo aplicacao ECM</b></td></tr> 
  <tr bgcolor="#cccccc"><td><b>Codigo</b></td><td><b>NASDAQ</b></td></tr> 
  <tr><td><a href="javascript:escolha('TOTVSv3')">TOTVS</a></td> 
  <td><a href="javascript:escolha('TOTVSv3')">TOTVSv3</a></td></tr> 
  <tr><td><a href="javascript:escolha('RM1')">RM</a></td> 
  <td><a href="javascript:escolha('RM1')">RM1</a></td></tr> 
  <tr><td><a href="javascript:escolha('DTS3')">Datasul</a></td> 
  <td><a href="javascript:escolha('dts3')">Dts3</a></td></tr> 
  <tr><td><a href="javascript:escolha('Lgx2')">Logix</a></td> 
  <td><a href="javascript:escolha('Lgx2')">Lgx2</a></td></tr> 
  </tbody>
  </table> 

  <!-- Fim dos dados --> 

  </body>
</html>

Para colocar o exemplo em prática no produto, basta publicar a definição de formulário a seguir informando o arquivo do zoom externo como anexo da definição de formulário.

Exemplo de Zoom.zip

 

Ao clicar em um dos itens da tela de zoom será chamada a função JavaScript escolha que ira enviar o valor para o campo cod_fornec no formulário do Fluig.



Serviços de Dados

O Fluig possui integração com dois tipos de serviços de dados, são eles: Dataset e Serviços Externos. Ambos podem ser usados em todos os eventos disponíveis para customização de definição de formulário.

Dataset

É um serviço de dados que fornece acesso às informações, independente da origem dos dados. O Fluig fornece Datasets internos que permitem acesso as entidades, como Usuários, Grupos de Usuários, entre outros. Consulte o cadastro de Datasets do Fluig para obter a relação completa dos Datasets disponíveis e seus respectivos campos.

Os exemplos abaixo utilizam a função getDatasetValues, disponível somente para os Datasets de entidade e definição de formulário(quando informado o número da definição de formulário). Para a utilização de Datasets customizados consulte o Guia de Referência Customização de Datasets.

 

Na função getDatasetValues, NÃO são retornados os valores de todos os campos por questões de segurança. Para obter todos os dados é utilizado o DatasetFactory, exemplificado em Desenvolvimento de Datasets.

Por exemplo, para acessar o Dataset de usuários do Fluigno evento displayFields de uma definição de formulário:

function displayFields(form,customHTML) {
     // Obtendo o usuario via dataset
     filter = new java.util.HashMap();
     filter.put("colleaguePK.colleagueId","adm");
     usuario = getDatasetValues('colleague',filter);
     form.setValue('RNC_colab_abertura',usuario.get(0).get("colleagueId"));
}


Também é possível fazer uma chamada aos Datasets dentro da definição de formulário através de funções JavaScript.

 

O acesso aos Datasets também pode ser realizado diretamente no formulário da definição de formulário. Por exemplo, para acessar o Dataset de usuário e inserir os valores nos campos do HTML:

 <html>
    <head>
        <title>
            Teste XMLRPC
        </title>
        <script language="javascript">      
            function init(){                            
                var filter = new Object();
                filter["colleaguePK.colleagueId"] = "adm";  
                var colleagues = getDatasetValues("colleague", filter);
                if(colleagues.length > 0){        
					document.getElementById("colleagueName").value = colleagues[0].colleagueName;
                	document.getElementById("colleagueId").value = colleagues[0].colleagueId;
               	 	document.getElementById("login").value = colleagues[0].login;
               	 	document.getElementById("extensionNr").value = colleagues[0].extensionNr;                
					document.getElementById("groupId").value = colleagues[0].groupId;
					document.getElementById("mail").value = colleagues[0].mail;
                }else{
                    alert("Nenhum Usuário Encontrado");
				}
            }
        </script>
    </head>
    <script src="../vcXMLRPC.js"></script>
    <body onload="init()">
    <form id="form1">
        <b> Nome do Usuário: </b>
        <input type="text" name="colleagueName" id="colleagueName" />
	    <br><br>    
		<b> Matricula do Usuário: </b>
        <input type="text" name="colleagueId" id="colleagueId" />
		<br><br>
		<b>Login do Usuário:</b>
        <input type="text" name="login" id="login" />
        <br><br>            
		<b> Ramal do Usuário: </b>
        <input type="text" name="extensionNr" id="extensionNr" />
        <br><br>
        <b> Grupo do Usuário: </b>
        <input type="text" name="groupId" id="groupId" />
        <br><br>
        <b> E-mail do Usuário: </b>
        <input type="text" name="mail" id="mail" />
        <br><br>
    </form>
    </body>
</html>

 

O Dataset para definição de formulário utiliza a mesma chamada do Dataset de entidades, como no caso do usuário. Entretanto ao invés de passarmos como parâmetro o nome do Dataset passaremos o número da definição de formulário, por exemplo:

 

function displayFields(form,customHTML) {
     // Obtendo o usuario via dataset
     filter = new java.util.HashMap();
     filter.put("RNC_nr_solicitacao",new java.lang.Integer(20));
     fichas = getDatasetValues(Number(676),filter);
	 log.info("Usuário de Abertura: "+ fichas.get(0).get("RNC_colab_abertura"));
}

 

Download de exemplo de Formulário Combobox e Dataset: form.html.

 

DataService

É um serviço de dados que permite o acesso de aplicações de terceiros através do Fluig. Este serviço de dados suporta dois tipos de conexão, são eles: AppServer do Progress® e Web Services.

Os serviços de dados são cadastrados e configurados a partir da função Visualização de Serviços do Fluig Studio.

Para mais informações sobre o cadastro dos serviços consulte: Integração com Aplicativos Externos. E para informações de utilização dos serviços nos eventos consulte: Desenvolvimento de Workflow.


Pai Filho

A técnica Pai X Filho foi modificada e agora a posição da tag tablename é feita dentro da tag "table" do código html.

No novo modelo implementado agora o parser do fichário aplicará as mudanças do pai filho da seguinte forma:

<table tablename="teste"> - A propriedade tablename determina que Agora abaixo dessa tabela será implementado um sistema de pai filho dentro da definição de formulário. A tag <table> terá seus parâmetros varridos na busca de outros parâmetros relacionados à técnica que serão explicados mais adiante nesse texto. Será criada uma outra <table> ao redor da tabela principal que conterá um  botão que permite adicionar novos filhos. Isso não ocorrerá apenas em casos em que a propriedade noaddbutton também seja informada em conjunto com  a propriedade tablename.                                                                                                    

<TR> (primeiro abaixo do table) - A primeira tag de <TR> encontrada dentro da tabela é visualizada como uma tag que conterá os labels da tabela pai filho a esta tag será adicionada uma coluna <TD> contendo o ícone e a função de eliminar filhos existentes em tela. Está nova coluna será a primeira coluna a esquerda da tabela.

<TR> (Segundo abaixo do table) - A técnica pai filho irá ocultar a linha <TR> original e transforma lá no seu “template mestre” para criação dos filhos daquela tabela. Cada vez que o botão “novo” for acionado todo o conjunto de campos existentes dentro desse segundo <TR> será replicado em tela com os dados iniciais definidos para estes campos.

</table>  - Fim do escopo da técnica.

 

A técnica também suporta novos atributos que podem ser passados eu usados para customizar a técnica pai e filho. São elas:

noaddbutton - Remove o botão “adicionar” da tela no momento da edição do formulário. Isso permite ao desenvolvedor escolher aonde ele vai colocar a função  que criará os filhos em tela podendo amarrar a chamada da função em um link texto ou uma figura ou outro objeto do html.

<table tablename="teste" noaddbutton=true>


nodeletebutton - Remove o botão “lixeira” da tela no momento da edição do registro de formulário. Isso permite ao desenvolvedor impedir a eliminação dos registros ou definir outra forma de executar a função que removerá os filhos da tabela.

 <table tablename="teste" nodeletebutton=true>


addbuttonlabel - Determina que texto será posto no botão de adicionar filhos da técnica. Caso não seja informado o botão virá com o texto padrão (novo).                                    

 <table tablename="teste" addbuttonlabel="Adicionar novo ingrediente">

                         

addbuttonclass - Permite definir qual classe css será utilizada pelo botão. Essa classe css deverá estar disponível no documento html do fichário.

 <table tablename="teste" addbuttonclass="wdkbuttonClass">


deleteicon - Permite determinar qual será a imagem que funcionará como ícone da eliminação de filhos em tela. Essa imagem deverá ser um anexo da definição de formulário e deverá ser informada na classe como uma imagem qualquer utilizada como anexo na definição de formulário.

<table tablename="teste" deleteicon="teste.jpg">       


customFnDelete - Permite a customização da função que é chamada ao clicar no botão que elimina um filho da tabela. A função customizada deverá estar disponível no documento html da definição de formulário e, obrigatoriamente, chamar a função padrão.

<table tablename="teste" customFnDelete="fnCustomDelete(this)">
    function fnCustomDelete(oElement){

    //Customização
	alert ("Eliminando filho!");

    // Chamada a funcao padrao, NAO RETIRAR
    fnWdkRemoveChild(oElement);

    //Customização
    alert ("Filho eliminado!");
}

 

É possível usar a combinação de um ou mais atributos na mesma tabela pai filho. Contudo se a propriedade noaddbutton for utilizada os valores das propriedades addbuttonlabel e addbuttonclass serão ignoradas. Não será gerada uma mensagem de erro na publicação ou versionamento dessa definição de formulário, porém no momento da edição do formulário a mesma não irá apresentar o botão padrão que permite cadastrar novos filhos na definição de formulário. A propriedade deleteicon não é afetada pela propriedade noaddbutton. Exemplo de uso combinado de parâmetros:

<table tablename="teste" addbuttonlabel="Adicionar novo ingrediente" addbuttonclass="wdkbuttonClass" deleteicon="teste.jpg">

  • A técnica 2.0 do Pai filho não é retro-compatível com a primeira implementação. Definição de formulários que foram feitas com a primeira técnica deverão ser retrabalhados para utilizar este nova técnica.
  • Campos de uma tabela pai e filho não estão disponíveis para serem utilizados como descrição dos registros de formulários na configuração do formulário.

  • Campos de uma tabela pai e filho não devem ser colocados no "Head" ou "Foot" de um HMTL pois eles não serão considerados, coloque os campos apenas no "Body".


  • Necessário incluir as seguintes chamadas javascript no "Head" do formulário, para o correto funcionamento nas versões mobile:

    <script type="text/javascript" src="/portal/resources/js/jquery/jquery.js" charset="utf-8"></script>
    <script type="text/javascript" src="/portal/resources/js/mustache/mustache-min.js" charset="utf-8"></script>
    <script type="text/javascript" src="/portal/resources/style-guide/js/fluig-style-guide-project.min.js" charset="utf-8"></script>



A técnica 2.0 do pai Filho não aceita todos os componentes html, mas aceita os principais, sendo os homologados pelo produto os tipos: text, radio button, checkbox, select, select multiple, hidden, textarea, image e button.

Expanda a macro e veja o exemplo a seguir:

<HTML>
<HEAD>
  <TITLE>WebDesk</TITLE>
  <LINK REL=STYLESHEET HREF="/webdesk203/wdk/global.css">
  <script type="text/javascript" src="/portal/resources/js/jquery/jquery.js" charset="utf-8"></script>
  <script type="text/javascript" src="/portal/resources/js/mustache/mustache-min.js" charset="utf-8"></script>
  <script type="text/javascript" src="/portal/resources/style-guide/js/fluig-style-guide-project.min.js" charset="utf-8"></script>
</HEAD>
<BODY scroll=yes>
<span class="NumSecao">
<strong>&nbsp;Cadastro</strong></span>
<HR>
<br>
<form>
<table>
  <tr> 
    <td align="right" width="100" class="Labels"><b>Data:</b></td>
    <td class="Normal"><strong><input type="text" size="30" name="data"></strong></td>
  </tr>
  <tr> 
    <td align="right" width="100" class="Labels"><b>Solicitação:</b></td>
    <td class="Normal"><strong><input type="text" size="30" name="num_solic"></strong></td>
  </tr>
  <tr> 
    <td align="right" width="100" class="Labels"><b>Atividade:</b></td>
    <td class="Normal"><input type="text" size="30" name="num_ativ"></td>
  </tr>
  <tr> 
    <td align="right" width="100" class="Labels"><b>Processo:</b></td>
    <td class="Normal"><input type="text" size="30" name="cod_proc"></td>
  </tr>
  <tr> 
    <td align="right" width="100" class="Labels"><b>Versão:</b></td>
    <td class="Normal"><p><input type="text" size="30" name="ver_proc"></p></td>
  </tr>
  <tr> 
    <td align="right" width="100" class="Labels"><b>Usuário:</b></td>
    <td class="Normal"><p><input type="text" size="30" name="usuario"></p></td>
  </tr>
  <tr> 
    <td align="right" width="100" class="Labels"><b>Empresa:</b></td>
    <td class="Normal"><p><input type="text" size="30" name="empresa"></p></td>
  </tr>
  <tr>
    <td align="right" width="100" class="Labels"><b>Observações:</b></td>
    <td class="Normal"><p><input type="text" size="30" name="obs"></p></td>
  </tr>
   <td class="label">
        Autoriza?
        <input type="radio"
           name="aut"
           id="aut"
           value="branco"
           style="display:none">
        Sim:                                       
            <input name="aut"
               type="radio"
               value="aut_yes" checked>                        
        Não:
            <input name="aut"
               type="radio"
               value="aut_no">
    </td> 
</table>
<table>
  <tr>
    <td><b>Responsáveis:</b></td><br></br>
        <table border="1" tablename="teste" addbuttonlabel="Adicionar Responsável">
            <thead>
                <tr>
                    <td>
                        <b>Responsável:</b>
                    </td>
                    <td>
                          Check
                    </td>
                    <td>
                        Observação
                    </td>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>
                        <select name="colaboradores" dataset="colleague" datasetkey="colleagueName" datasetvalue="colleagueName"></select>
                    </td>
                    <td>
                        <input type="checkbox" name="validado" value="a">
                    </td>
                    <td>
                        <input type="text" name="mat_er_ial" id="mat_er_ial">
                    </td>
                </tr>
            </tbody>
        </table>
  </tr>
</table>
</form>
</BODY>
</HTML>



Pai Filho Radio Button

Para utilizar campos radio button, além da definição padrão do componente html, é necessário que seja utilizado o atributo ‘value’ para os dados serem salvos corretamente.


<table border="1" tablename="teste" addbuttonlabel="Adicionar Filho"  nodeletebutton="true">
	<thead>
		<tr>
			<td><b>Nome</b></td>
			<td><b>Idade</b></td>
			<td><b><font face =	"arial" size=5 color ="blue">Sim:</b></td>
		 	<td><b><font face = "arial" size=5 color ="blue">Não:</b></td>
	 	</tr>
	</thead>
	<tr>
		<td><input type="text" name="nomefilho"></td>
		<td><input type="text" name="idadefilho"></td>
 		<td><input type="radio" name="nameradiofilho" id = "idsimfilho" value="ant_yes"></td>
	 	<td><input type="radio" name="nameradiofilho" id = "idnaofilho" value="ant_no"></td>
	</tr>
</table>

 

Eventos de Formulário Pai Filho

Para facilitar a manipulação dos dados em uma customização de formulário que faz uso da técnica Pai Filho, foram disponibilizados os métodos listados a seguir. Ambos são chamados a partir do objeto form que é passado como parâmetro nas funções de customização de formulários.

 

getChildrenFromTable

Esse evento retorna um mapa com todos os campos filhos de um Pai Filho a partir do seu tablename.

 

getChildrenIndexes

Esse evento retorna os índices dos registros (linhas) contidos em um Pai Filho a partir do seu tablename.

 

Exemplo:

 

function validateForm(form){
    var indexes = form.getChildrenIndexes("tabledetailname");
    var total = 0;
    for (var i = 0; i < indexes.length; i++) {
        var fieldValue = parseInt(form.getValue("valor___" + indexes[i]));
        if (isNaN(fieldValue)){
            fieldValue = 0;
        } 
        total = total + fieldValue;
        log.info(total);
    }
    log.info(total);
    if (total < 100) {
        throw "Valor Total da requisição não pode ser inferior a 100";
    }
}

 

 

Formulários para dispositivos móveis

Com a inclusão de definição de formulários que suportem a visualização em dispositivos móveis, é possível movimentar solicitações Workflow através destes dispositivos e realizar o preenchimento das informações da definição de formulários HTML, garantindo maior mobilidade e agilidade para realizar movimentações de solicitações workflow.

Para incluir um novo fichário com suporte de dispositivos móveis, realize o procedimento padrão para exportação da definição de formulário e selecione os campos que irão compor o formulário mobile na tela antes da conclusão da exportação. Após a exportação será incluindo também outro arquivo HTML e marcando-o como "mobile" na pasta forms do projeto Fluig. 

Veja na imagem a seguir a tela de seleção mobile na exportação de uma definição de formulário:

Figura 15 - Definição de formulário mobile.

 

Após exportado o formulário deve ficar conforme a seguir:

Figura 16 - Resultado formulário mobile.

 

Pai Filho para dispositivos móveis

Os campos que empregam a técnica de pai e filho não são inseridos no formulário gerado automaticamente para dispositivos móveis pelo Fluig. Porem o produto lhe permite desenvolver um formulário customizado para dispositivos móveis consultando estes campos.

A edição de campos pai e filho através de dispositivos mobile não é possível, mesmo em formulários customizados. Somente consulta.

 

A consulta aos campos pai e filho em dispositivos móveis é realizada por meio de funções javaScript, disponíveis dentro do objeto masterList no momento da exibição do formulário. São elas:

getValue

Retorna uma string com o valor de um campo pai e filho, recebendo como parâmetros o numero de sequencia do filho e o nome do campo.

masterList.getValue(sequence,field);


getValues

Retorna um objeto com todos os valores dos campos pai e filho, agrupados pelo numero de sequencia. Este método não possui parâmetros.

masterList.getValues();

 

getValuesBySequence

Retorna um objeto com todos os valores do campos de uma determinada sequencia. Recebe como paramento o numero da sequencia.

masterList.getValuesBySequence(sequence);


getValuesByField

Retorna todas as sequencias e valores de um determinado campo. Recebe como parâmetro o nome do campo.

masterList.getValuesByField(field);

 

Exemplos: Formulários Pai Filho + Eventos

 

 

Tradução de formulários

Para traduzir formulários é necessário utilizar a função i18n.translate(“literal_da_tradução”) nos pontos do arquivo HTML que devem ser traduzidos, conforme exemplo a seguir:

<label>i18n.translate("nm_cliente")</label>
<input name=”nm_cliente”>
<br>
<label>i18n.translate("contato_cliente")</label>
<input name=”contato_cliente”>

 

 

As literais e seus respectivos valores são informados em arquivos de propriedades com a extensão .properties para cada um dos idiomas desejados. Os idiomas suportados para a tradução são os mesmos suportados pelo Fluig:
  • Português (pt_BR);
  • Inglês (en_US);
  • Espanhol (es).

 

Os arquivos contendo as literais têm a seguinte nomenclatura:

 

Os arquivos de propriedades são criados de acordo com os passos apresentados a seguir:

 

  • Para gerar os arquivos de propriedades, na visão Explorador de Pacotes, deve-se acessar o arquivo HTML do formulário a ser traduzido, clicar com o botão direito e acessar a opção Externalizar Strings.

Figura 1 - Menu Contextual Externalizar Strings.

 

 

  • Os arquivos contendo as literais são criados na pasta do formulário.

Figura 2 - Arquivos Properties na Pasta do Formulário.


 

  • Informe os valores correspondentes às literais para o idioma de cada arquivo.

Figura 3 - Edição de um Arquivo Properties.


Ao exportar um formulário para o Fluig, os arquivos de propriedades contendo as literais são publicados como anexos dele.
O formulário é apresentado no idioma que está configurado para o usuário corrente.

 

Traduzindo Eventos de formulários 

Da mesma forma que é possível traduzir a interface do formulário é possível traduzir também mensagem retornadas nos eventos do formulário. Para isso basta utilizar a função i18n.translate dentro dos eventos passando uma propriedade que esteja pré-definida no arquivos .properties deste mesmo formulário. Abaixo exemplo de uma implementação que irá retornar para o usuário uma mensagem de acordo com o definido no arquivo properties.

 

 

if (form.getValue('meeting') == null || form.getValue('meeting').trim().length() == 0) {
		throw i18n.translate("proidade_definida_no_arquivo_properties");
	}