Grid
A principal ferramenta de apresentação de dados do Web Framework é a grade. A seguir será explicado o básico sobre o desenvolvimento da grade. Para uma visão mais aprofundada, a documentação da API deve ser consultada.
Declaração da grade
Uma grade é construída no contexto de um processo. Assim, a forma mais comum de declarar uma grade
é por meio do método grid
da classe Process
. Em arquivos .ip ou .il (processos e relatórios
respectivamente), o objeto do processo corrente pode ser acessado por this
. Dessa forma, a
declaração de uma grade poderia ser:
const grid = this.grid('nome da grade');
ou
this.ds = classes.getCachedDataSet(-2090000000);
const grid = this.grid('exemplo', this.ds);
Este método de Process
pode ser usado para criar uma grade ou acessar pelo nome a instância já
criada de uma grade.
O terceiro e o quarto parâmetros são opcionais, sendo respectivamente a chave da classe que terá
definição de campos da grade e o objeto da grade mestre (fazendo uma relação masterDetail
). Para
mais detalhes de como declarar uma grade no processo, ver a documentação de
Process.grid.
Objetos da classe Grid
também possuem uma série de propriedades que podem ser editadas para
modificar o comportamento da grade, como por exemplo, definir se ela pode editar, inserir, apagar,
exportar ou duplicar registros. Para mais detalhes dessas propriedades, ver a documentação de
Grid.
Registro de eventos
Após declarar a grade, normalmente são registrados os eventos, caso necessário. Eventos geralmente são disparados durante a construção da grade, como na definição de campos, por exemplo, e também antes e depois de ações na grade, como remoção, inclusão, confirmação de edição etc.
No exemplo a seguir, um evento pré-remoção é registrado:
grid.on('beforeDelete', function (evt) {
if (evt.grid.ds.num('iNumber') < 10) {
throw new Error('Registros com valores abaixo de 10 não podem ser removidos.');
}
});
Para mais detalhes sobre cada evento, ver a documentação de eventos da grade.
Definição dos campos
Para acessar ou definir o campo de uma grade, utiliza-se o método field
da classe Grid
.
Com o objeto field, é possível ler e editar o dado do campo do registro corrente, ou modificar
suas propriedades.
Exemplo:
const fld = grid.field('non_negative');
const value = fld.getValue();
if (value < 0) {
fld.setValue(0);
}
Por vezes, a grade declarada precisa ter seus campos definidos ou modificados no momento de sua construção, seja por não possuírem uma definição de classe de onde pegar a definição dos campos, seja por precisarem ter uma customização específica para o processo.
Para isso, usa-se o evento defineFields
.
grid.on('defineFields', function (evt) {
let fld = evt.grid.field('field_1');
fld.label = 'Field 1';
fld.help = 'Ajuda do campo 1';
fld.on('lookupDisplay', function (evt) {
evt.displayValue = DBKey.from(evt.key).str('iName');
});
fld = evt.grid.field('field_2');
fld.label = 'Field 2';
fld.readonly = true;
fld = evt.grid.field('field_3');
fld.visible = false;
});
Como é possível notar pelo exemplo acima, os campos podem ter propriedades modificadas e eventos registrados. Para mais detalhes, ver a documentação de Field.
Registros
Algumas propriedades da grade que permitem lidar com os registros:
- maxRecordCount: define o número máximo de registros a serem exibidos por página no modo tabela.
- maxSelectedRecords: define o número máximo de registros que podem ser selecionados.
- selectedRecords: guarda a lista de bookmarks dos registros selecionados em um array.
- unselectableRecords: define por meio de um array de bookmarks quais os registros não podem ser selecionados.
Também é possível percorrer todos os registros e acessar os valores de seus campos por meio do
dataset da grade, acessível pela propriedade ds
. Em alguns casos, é recomendado que um clone
desse dataset seja feito, para evitar modificar apresentação dos dados para o usuário. Por exemplo,
quando for necessário percorrer os registros desse dataset, filtrá-lo ou modificar seus índices.
Para criar o clone do dataset, faça:
const clone = grid.ds.newSharedDataSet();
O método newSharedDataSet
também admite um parâmetro com opções, como por exemplo
ds.newSharedDataSet({ sharedDelta: true })
para que o dataset tenha o delta compartilhado.
Para mais informações, acesse a
documentação da API.
Botões
Uma grade pode conter botões que desempenham ações a serem definidas pelo desenvolvedor.
Para declarar um botão, basta utilizar o método button
da classe Grid
. Esse método cria um
botão ou acessa pelo nome a instância de um botão já criado.
Exemplo:
grid.button('Tornar maiúsculas', function (bt){
var grid = bt.parent
var ds = grid.ds
var selectedRecords = grid.selectedRecords
for (var i = 0; i < selectedRecords.length; ++i){
ds.bookmark = selectedRecords[i];
ds.setField('NOME', ds.str('NOME').toUpperCase());
}
});
O segundo parâmetro não precisa ser necessariamente uma função. Pode também ser o nome de uma atividade ou interação. Existem mais três parâmetros que definem, respectivamente, a ordem do botão, a chave do processo (para os casos em que o botão abre uma interação ou atividade em um processo diferente do atual) e se a interação ou atividade deverá ser aberta em nova aba.
Os botões visíveis da grade podem ser controlados pela propriedade visibleButtons
, que é um array
de objetos da classe Button
ou de strings com os nomes dos botões.
Para mais informações do botão, acesse Grid.button e Button.
Botão “Duplicar registro” na grade
Devido a necessidade cada vez mais constante de se criar registros com base em outros, foi criado o botão “Duplicar registro” para todas as grades.
O comportamento
Por padrão o botão “Duplicar registro” irá duplicar todos os campos com exceção da grade e dos campo que possuam os nomes IKEY, CHAVE, IVERSION e VERSAO. Os campos de nome ICODE, CODIGO, INAME e TITULO serão duplicados por padrão com a adição do sufixo “+”.
Este comportamento pode ser alterado definindo a propriedade duplicateMode do campo. Esta propriedade pode receber os seguintes valores:
- DuplicateMode.NONE: o valor do campo não será duplicado.
- DuplicateMode.COPY: o valor do campo será duplicado integralmente, caso este campo seja uma grade os dados dela serão duplicados seguindo o comportamento padrão do botão.
- DuplicateMode.COPY_ADDING_SUFFIX: o valor do campo será duplicado com a adição do sufixo “+”.
Alterando o comportamento
Suponhamos que queremos que uma grade detalhe tenha seus dados duplicados para um novo registro e que os items do seu campo “detailField” não recebam sufixo. Podemos fazer como no código abaixo:
Exemplo:
const DuplicateMode = require('@nginstack/web-framework/lib/classdef/DuplicateMode');
const CLASS_KEY = 12345;
const grid = this.grid('masterGrid', classes.getCachedDataSet(CLASS_KEY), CLASS_KEY);
grid.on('defineFields', function (evt) {
const field = evt.grid.field('detailGrid');
field.duplicateMode = DuplicateMode.COPY;
field.grid.on('defineFields', function (evt) {
evt.grid.field('detailField').duplicateMode = DuplicateMode.COPY;
});
});
grid.write();
Alterando o comportamento via x-class
É possível informar que uma determinada classe não pode ter seus dados duplicados por padrão ara isso basta adicionar um x-class na classe desejada e definir a propriedade canDuplicate.
Exemplo: this.canDuplicate = false;
Os eventos
Há dois eventos que são executados a cada clique no botão “Duplicar registro” são eles:
beforeDuplicate
: Executado antes de iniciar o processo de duplicação do registro;afterDuplicate
: Executado ao terminar o processo de duplicação do registro;
const DuplicateMode = require('@nginstack/web-framework/lib/classdef/DuplicateMode');
const CLASS_KEY = 12345;
const grid = this.grid('masterGrid', classes.getCachedDataSet(CLASS_KEY), CLASS_KEY);
grid.on('defineFields', function (evt) {
const field = evt.grid.field('detailGrid');
field.duplicateMode = DuplicateMode.COPY;
field.grid.on('defineFields', function (evt) {
evt.grid.field('detailField').duplicateMode = DuplicateMode.COPY;
});
});
grid.on('beforeDuplicate', function(evt) {
evt.grid.process.alert('Duplicando registros');
});
grid.on('afterDuplicate', function(evt) {
evt.grid.process.alert('Registros duplicados com sucesso');
});
grid.write();
Botão “Mostrar/Ocultar” chaves na grade
Ao clicar no botão “Mostrar/Ocultar chaves” o comportamento visual do campo definido pelo desenvolvedor será sobreposto, permitindo ficar visível mesmo que tenha sido ocultado em um determinado modo de visão da grade.
Caso haja o desejo de não mostrar as chaves de uma determinada grade, foi criada a propriedade Grid. prototype.enableToggleKeyButton, esta permite desabilitar o botão.
Exemplo:
const CLASS_KEY = 12345;
const grid = this.grid('masterGrid', classes.getCachedDataSet(CLASS_KEY), CLASS_KEY);
grid.enableToggleKeyButton = false;
grid.write();