Guia completo do sistema de eventos do Formbuilder.js: save, change e demais eventos

O Formbuilder.js é uma ferramenta robusta para construção de formulários web, e seu sistema de eventos é o mecanismo central para personalizar interações e estender funcionalidades. Seja para capturar o salvamento de formulários, alterações em campos ou ações do usuário, os eventos permitem interceptar e reagir a essas operações de forma eficiente.

Por que utilizar um sistema de eventos?

Em cenários de construção de formulários web, responder em tempo real às ações do usuário é fundamental. O sistema de eventos do Formbuilder.js é construído sobre o módulo Events do Backbone.js, oferecendo uma arquitetura orientada a eventos. Com ele, é possível:

  • Sincronizar dados do formulário em tempo real
  • Rastrear o comportamento do usuário para análise
  • Implementar regras de negócio customizadas
  • Integrar serviços externos e APIs

Visão geral dos eventos disponíveis

O Formbuilder.js disponibiliza diversos tipos de eventos, organizados nas seguintes categorias:

1. Evento save — O coração do salvamento

O evento save é o evento de ciclo de vida mais relevante do Formbuilder.js. Ele é disparado quando o usuário clica no botão de salvar ou quando o autosave é ativado. O payload transportado contém o JSON completo do formulário, pronto para processamento no backend.

Exemplo de uso básico:

const formEditor = new Formbuilder({ selector: '#fb-container' });

formEditor.on('save', (jsonData) => {
  const parsed = JSON.parse(jsonData);
  console.log('Dados persistidos:', parsed);
});

Momentos em que o save é disparado:

  • Clique manual no botão de salvar
  • Autosave habilitado (intervalo padrão de 5 segundos)
  • Após qualquer modificação nos dados do formulário

2. Evento change — Monitoramento em tempo real

O evento change é emitido sempre que qualquer campo do formulário sofre modificação — incluindo conteúdo, opções ou configurações. É a escolha ideal para previews em tempo real e validação instantânea.

Referência no código-fonte: src/scripts/main.coffee

handleFormUpdate: ->
  return if @updatingBatch
  @formSaved = false
  @saveFormButton.removeAttr('disabled').text(Formbuilder.options.dict.SAVE_FORM)

3. Evento add — Notificação de novos campos

Disparado quando um novo campo é inserido no formulário. Pode ser usado para:

  • Coletar estatísticas sobre tipos de campos adicionados
  • Inicializar configurações específicas de novos campos
  • Atualizar elementos da interface relacionados

4. Evento destroy — Tratamento de remoção

Emitido quando um campo é excluído, sendo útil para limpeza de recursos e atualização de estados dependentes.

5. Evento reset — Reinicialização do formulário

Disparado quando o formulário é redefinido ou recarregado, permitindo executar lógicas de reinicialização.

Aplicações práticas

Cenário 1: Autosave e sincronização de dados

O Formbuilder.js possui um recurso nativo de autosave controlado pela opção AUTOSAVE. Quando ativo, o evento save é disparado automaticamente a cada 5 segundos:

const formEditor = new Formbuilder({
  selector: '#fb-container',
  options: {
    AUTOSAVE: true
  }
});

formEditor.on('save', (payload) => {
  fetch('/api/forms/persist', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: payload
  });
});

Cenário 2: Validação instantânea

Combinando o evento change com uma função de validação, é possível verificar o formulário em tempo real:

formEditor.on('change', () => {
  const currentData = formEditor.getData();
  const validationErrors = runValidation(currentData);
  
  if (validationErrors.length > 0) {
    displayErrors(validationErrors);
  }
});

Cenário 3: Análise de comportamento do usuário

Audite as interações do usuário monitorando múltiplos eventos simultaneamente:

const actionLog = [];

formEditor.on('add', (fieldData) => {
  actionLog.push({
    action: 'insert',
    fieldType: fieldData.field_type,
    time: Date.now()
  });
});

formEditor.on('destroy', (fieldData) => {
  actionLog.push({
    action: 'delete',
    fieldType: fieldData.field_type,
    time: Date.now()
  });
});

Configurações avançadas e eventos customizados

Endpoint HTTP personalizado

É possível definir um endpoint e método HTTP próprios para o salvamento:

const formEditor = new Formbuilder({
  selector: '#fb-container',
  options: {
    HTTP_ENDPOINT: '/api/v2/forms',
    HTTP_METHOD: 'PUT'
  }
});

Gerenciamento de listeners

Registrar um listener:

formEditor.on('save', onSaveCallback);
formEditor.on('change', onChangeCallback);

Listener de execução única:

formEditor.once('save', (payload) => {
  // Executado apenas uma vez
});

Remover um listener:

formEditor.off('save', onSaveCallback);

Disparo de eventos customizados

Embora o Formbuilder.js forneça eventos nativos, a instância pode emitir eventos próprios:

formEditor.trigger('myCustomEvent', { customProp: 'value' });

Boas práticas e otimização de performance

1. Debounce em eventos frequentes

Para o evento change, que dispara com alta frequência, recomenda-se aplicar debounce:

const throttledSave = _.debounce((payload) => {
  // Lógica de salvamento
}, 1000);

formEditor.on('save', throttledSave);

2. Gerenciamento de memória

Remova listeners desnecessários para evitar vazamentos de memória:

// Ao destruir o componente
function cleanup() {
  formEditor.off('save', handleSave);
  formEditor.off('change', handleChange);
}

3. Tratamento de erros

Adicione tratamento de exceções nos handlers de eventos:

formEditor.on('save', (payload) => {
  try {
    // Lógica de processamento
  } catch (err) {
    console.error('Falha ao salvar:', err);
    // Lógica de fallback ou notificação ao usuário
  }
});

Debug e resolução de problemas

Problemas comuns

  1. Eventos não disparam
    • Verifqiue se a instância do Formbuilder foi inicializada corretmaente
    • Confirme se o nome do evento está correto
    • Garanta que o listener foi registrado no momento adequado
  2. Problemas de formato de dados
    • O evento save retorna uma string JSON que precisa ser parseada
    • Confirme se a API backend aceita o formato esperado
  3. Problemas de performance
    • Evite operações pesadas dentro de handlers de eventos
    • Considere Web Workers para cálculos intensivos

Dica de depuração

// Capturar todos os eventos disparados
formEditor.on('all', (eventName, ...args) => {
  console.log(`Evento disparado: ${eventName}`, args);
});

Análise do código-fonte

A implementação central do sistema de eventos está localizada nos seguintes pontos:

  1. Mecanismo de binding: `src/scripts/main.coffee```` constructor: (opts={}) -> _.extend @, Backbone.Events

  2. Disparo do evento save: `src/scripts/main.coffee```` if Formbuilder.options.HTTP_ENDPOINT then @doAjaxSave(payload) @formBuilder.trigger 'save', payload

  3. Tratamento do evento change: `src/scripts/main.coffee```` @collection.bind 'change', @handleFormUpdate, @

Tags: Formbuilder.js Backbone.js Event-Driven Architecture Web Forms javascript

Publicado em 7-13 20:51