Eventos de formulário

Após o formulário ser criado e o template HTML do formulário ser adicionado ao DOM, a aplicação dispara os seguintes eventos de formulário durante o ciclo de vida do formulário:

  • on_view_form_created - o evento é disparado quando o formulário foi criado mas ainda não exibido

  • on_view_form_shown - o evento é disparado quando o formulário foi exibido

  • on_view_form_close_query - o evento é disparado quando uma tentativa de fechar o formulário é feita

  • on_view_form_closed - o evento é disparado quando o formulário foi fechado

  • on_view_form_keydown - o evento é disparado quando ocorre um evento de pressionar tecla no formulário

  • on_view_form_keyup - o evento é disparado quando ocorre um evento de soltar tecla no formulário

Para outros tipos de formulário – edit, filter e param – substitua ‘view’ pelo tipo de formulário, por exemplo on_edit_form_created para formulário de edição.

Primeiro vamos explicar como usar o evento on_view_form_created.

Quando o usuário clica em um item do menu, a aplicação executa o método view do item correspondente da árvore de tarefas, este método cria um formulário usando seu template HTML e dispara primeiro o evento on_view_form_created da tarefa.

Quando você cria um novo projeto, o módulo client da tarefa já contém o código, incluindo o manipulador de evento on_view_form_created. Esse manipulador de evento é executado toda vez que um formulário de visualização é criado e define o comportamento padrão dos formulários de visualização.

Você pode abrir o módulo client da tarefa para ver este manipulador de evento. Se precisar alterar o comportamento padrão de todos os formulários de visualização do projeto, deve fazê-lo aqui.

Abaixo descrevemos as principais etapas que ele realiza:

  • Inicializa o view_form e table_options que são usados por alguns métodos quando o formulário de visualização e a tabela são criados.

  • Atribui manipuladores de eventos JQuery para botões padrão a métodos do item, dependendo dos direitos do usuário. No exemplo abaixo, o botão de deletar é inicializado:

    if (item.can_delete()) {
        item.view_form.find("#delete-btn").on('click.task', function(e) {
            e.preventDefault();
            item.delete_record();
        });
    }
    else {
        item.view_form.find("#delete-btn").prop("disabled", true);
    }
    
  • Executa o on_view_form_created manipulador de evento do grupo do item e o on_view_form_created do item, caso estejam definidos:

    if (!item.master && item.owner.on_view_form_created) {
        item.owner.on_view_form_created(item);
    }
    
    if (item.on_view_form_created) {
        item.on_view_form_created(item);
    }
    
  • Cria uma tabela para exibir os dados do item e tabelas para detalhes, se forem especificadas, chamando o método create_view_tables

  • Executa o método open, que obtém o conjunto de dados do item do servidor.

  • Finalmente, retorna verdadeiro para evitar a chamada do on_view_form_created do grupo proprietário e do item, pois já foram chamados, veja o método _process_event abaixo.

Depois de inicializar os botões e antes de criar as tabelas, chamamos o manipulador de evento on_view_form_created do próprio item.

Por exemplo, no módulo client do item de faixas da aplicação demo, o seguinte manipulador de evento on_view_form_created está definido. Nele, alteramos o atributo height de table_options, criamos a cópia do invoice_table, definimos seus atributos e chamamos o método create_table que cria uma tabela para exibir seus dados.

function on_view_form_created(item) {
  item.table_options.height -= 200;
  item.invoice_table = task.invoice_table.copy();
  item.invoice_table.paginate = false;
  item.invoice_table.create_table(item.view_form.find('.view-detail'), {
      height: 200,
      summary_fields: ['date', 'total'],
  });
  item.alert('Double-click the record in the bottom table to see track sales.');
}

O módulo também possui o on_after_scroll manipulador de evento, que será executado quando o usuário se mover para a outra faixa e obterá as vendas dessa faixa.

Este exemplo explica o princípio do uso de eventos de formulário.

A ordem de disparo dos eventos depende do tipo de evento.

A ordem em que os eventos são gerados depende do tipo de evento.

Eventos de consulta de fechamento

Quando o usuário tenta fechar o formulário, o evento on_close_query é primeiramente disparado (se definido) para o item.

Se o manipulador de evento retornar true, o aplicativo fecha o formulário; caso contrário, se o manipulador de evento retornar false, o aplicativo mantém o formulário aberto. Caso contrário, o evento on_close_query é disparado (se definido) da mesma forma para o grupo do item e depois para o tarefa.

Por exemplo, por padrão, existe o on_edit_form_close_query manipulador de evento no módulo do cliente da tarefa:

function on_edit_form_close_query(item) {
    var result = true;
    if (!item.virtual_table && item.is_changing()) {
        if (item.is_modified()) {
            item.yes_no_cancel(task.language.save_changes,
                function() {
                    item.apply_record();
                },
                function() {
                    item.cancel_edit();
                }
            );
            result = false;
        }
        else {
            item.cancel_edit();
        }
    }
    return result;
}

Este código verifica se o registro foi modificado e, em seguida, abre a caixa de diálogo “Sim Não Cancelar”.

Se quisermos fechar o formulário sem essa caixa de diálogo, podemos definir o seguinte manipulador de evento no módulo do cliente do item:

function on_edit_form_close_query(item) {
    item.cancel()
    return true;
}

Eventos Keydown, Keyup

Esses eventos são disparados da mesma maneira que os eventos de consulta de fechamento, começando pelo item, mas se o manipulador de evento retornar true, os manipuladores de evento do grupo e da tarefa não são executados.

Por exemplo, por padrão, existe o on_edit_form_keyup manipulador de evento no módulo do cliente da tarefa:

function on_edit_form_keyup(item, event) {
    if (event.keyCode === 13 && event.ctrlKey === true){
        item.edit_form.find("#ok-btn").focus();
        item.apply_record();
    }
}

Este código salva as alterações do registro na tabela do banco de dados quando o usuário pressiona Ctrl+Enter.

Suponha que queremos salvar as alterações quando o usuário pressiona Enter. Então, escrevemos o seguinte manipulador de evento no módulo do cliente do item:

function on_edit_form_keyup(item, event) {
    if (event.keyCode === 13){
        item.edit_form.find("#ok-btn").focus();
        item.apply_record();
        return true;
    }
}

Neste caso, o manipulador de evento da tarefa não será chamado quando o usuário pressionar Enter.

Todos os outros eventos

Para outros eventos, o manipulador de evento da tarefa é chamado primeiro; se ele não retornar true, o manipulador de evento do grupo é executado, e se este também não retornar true, o manipulador de evento do item é chamado.

Esse mecanismo é implementado no método _process_event da classe Item no módulo jam.js.

_process_event: function(form_type, event_type, e) {
  var event = 'on_' + form_type + '_form_' + event_type,
      can_close;
  if (event_type === 'close_query') {
      if (this[event]) {
          can_close = this[event].call(this, this);
      }
      if (!this.master && can_close === undefined && this.owner[event]) {
          can_close = this.owner[event].call(this, this);
      }
      if (can_close === undefined && this.task[event]) {
          can_close = this.task[event].call(this, this);
      }
      return can_close;
  }
  else if (event_type === 'keyup' || event_type === 'keydown') {
      if (this[event]) {
          if (this[event].call(this, this, e)) return;
      }
      if (!this.master && this.owner[event]) {
          if (this.owner[event].call(this, this, e)) return;
      }
      if (this.task[event]) {
          if (this.task[event].call(this, this, e)) return;
      }
  }
  else {
      if (this.task[event]) {
          if (this.task[event].call(this, this)) return;
      }
      if (!this.master && this.owner[event]) {
          if (this.owner[event].call(this, this)) return;
      }
      if (this[event]) {
          if (this[event].call(this, this)) return;
      }
  }
}