Tabela pai e filho no Fluig: guia e erros comuns
Como criar uma tabela pai e filho no Fluig, adicionar linhas, ler os dados em eventos e datasets e evitar os erros que apagam a linha-modelo.
A tabela pai e filho é o recurso do Fluig para formulários com linhas repetidas, como itens de um pedido, rateios ou um checklist. É simples de começar, mas tem detalhes que causam horas de depuração. O principal deles: a linha que você vê não é a linha que está no HTML.
A estrutura mínima
<table id="itens" tablename="itens" noaddbutton="true" nodeletebutton="true">
<thead>
<tr>
<th>Produto</th>
<th>Quantidade</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" name="produto" class="form-control" /></td>
<td><input type="text" name="quantidade" class="form-control" /></td>
<td><button type="button" onclick="fnWdkRemoveChild(this)">Remover</button></td>
</tr>
</tbody>
</table>
<button type="button" onclick="wdkAddChild('itens')">Adicionar</button>
O atributo tablename é obrigatório. Sem ele, o Fluig não injeta os recursos da tabela. O sintoma é wdkAddChild is not defined no console e um botão Adicionar que parece morto. Um id não substitui esse atributo.
noaddbutton e nodeletebutton escondem os botões padrão, o que é útil quando você quer controlar a aparência.
Linha-modelo e linhas de dados
A linha do tbody não guarda dados. Ela é a linha-modelo, e o Fluig a mantém escondida para copiá-la a cada wdkAddChild. As linhas de dados são clones, com o nome do campo seguido de ___ e um índice:
produto linha-modelo, escondida
produto___1 primeira linha de dados
produto___2 segunda linha de dados
Aqui está a armadilha: a linha-modelo e os clones têm os mesmos atributos detail e detailname. Se o seu código usar esses atributos para limpar ou esconder linhas, ele atinge os dois.
Em processos que acompanhamos, isso causou três problemas parecidos:
- Uma rotina que apagava
tr[detail="true"]removeu também a linha-modelo. Depois disso,wdkAddChildnão tinha mais o que copiar. - Um filtro que ignorava
tr[detailname]deixou de contar as linhas reais, e o resumo ficou zerado. - Um CSS que escondia
tr[detailname]com!importantsumiu com todas as linhas.
A regra é separar modelo e dado pelo sufixo:
// Linhas de dados, sem pegar a linha-modelo
$('input[name^="produto___"]').each(function () {
var indice = this.name.split("___")[1];
console.log(indice, this.value);
});
Adicionar uma linha com valores
wdkAddChild retorna o índice da nova linha, o que permite preencher os campos em seguida:
var indice = wdkAddChild("itens");
$("#produto___" + indice).val("Parafuso");
$("#quantidade___" + indice).val("10");
Para carregar a tabela ao abrir o formulário, faça isso dentro de $(function () { ... }), depois que a página estiver pronta.
Ler e gravar no servidor
Em um evento de processo:
var indices = hAPI.getChildrenIndexes("itens");
for (var i = 0; i < indices.length; i++) {
var produto = hAPI.getCardValue("produto___" + indices[i]);
log.info("[COMPRAS] item: " + produto);
}
A documentação lembra que esses dados só existem depois de salvos, portanto use eventos After.
Para adicionar uma linha pelo servidor, use hAPI.addCardChild:
var linha = new java.util.HashMap();
linha.put("produto", "Parafuso");
linha.put("quantidade", "10");
hAPI.addCardChild("itens", linha);
Ao remover várias linhas, percorra de trás para frente. A remoção pode reorganizar os índices, e um laço normal acaba pulando linhas.
Consultar a tabela por dataset
O dataset do formulário traz a tabela filha quando você informa o tablename, junto com os identificadores da ficha:
var c1 = DatasetFactory.createConstraint("tablename", "itens", "itens", ConstraintType.MUST);
var c2 = DatasetFactory.createConstraint("metadata#id", idFicha, idFicha, ConstraintType.MUST);
var c3 = DatasetFactory.createConstraint("metadata#version", versao, versao, ConstraintType.MUST);
var filhos = DatasetFactory.getDataset("ds_meu_formulario", null, new Array(c1, c2, c3), null);
O guia de dataset explica os demais filtros. Em volumes grandes, consultar a tabela de muitas fichas pelo dataset fica lento, e isso costuma pedir outra abordagem.
Bloquear campos da tabela
Evite form.setEnabled em campos pai e filho. Em nossos projetos, o Fluig alterou o nome do campo com um prefixo, e isso quebrou o JavaScript que o manipulava. Para travar uma coluna, use readonly por JavaScript ao carregar a tabela.
Lembre-se também de que disabled não é enviado no formulário. Esse e outros casos estão em erros silenciosos no Fluig.
Checklist de problemas
wdkAddChild is not defined: faltatablenamena<table>.- Adicionar não faz nada: a linha-modelo foi removida do DOM.
- Linhas somem na tela: algum CSS ou script esconde
tr[detailname]. - Valor não chega no evento: o evento roda antes de salvar. Use um evento After.
- Campo novo some: a definição do formulário precisa ser publicada de novo.
Perguntas frequentes
O que é tabela pai e filho no Fluig?
É uma tabela de formulário com linhas repetidas ligadas a uma mesma ficha, como os itens de um pedido.
Como adicionar uma linha por JavaScript?
Chame wdkAddChild("nomeDaTabela"). A função devolve o índice, que você usa para preencher os campos campo___indice.
Como ler os dados no servidor?
Use hAPI.getChildrenIndexes("tabela") para obter os índices e hAPI.getCardValue("campo___" + indice) para ler cada campo.
Formulários com muitas tabelas e regras costumam ser o ponto mais frágil de um processo. Se esse é o seu caso, a consultoria Fluig da MyQube pode ajudar. Vamos conversar.
Sua operação ainda depende de planilhas e retrabalho?
Agende uma conversa gratuita e receba um diagnóstico inicial dos seus gargalos operacionais.
Falar com a MyQubeOu conheça nosso serviço de Consultoria Fluig