O Formulário - bjverde/formDin GitHub Wiki

O Formulário é que dá nome do formDin (Formulário Dinâmico), lembrando o formDin iniciou em 2004 em uma época que a web era praticamente paginas estáticas. Então criar um formulário para envio de dados eram algo não trivial. Se esse formulário fosse dinâmico era algo muito desejado.

Todo formulário é criado com a classe TForm que é uma das classes mais importantes do formDin. Veja a lista completa das principais classes por tamanho

Lembra que o formDin não final irá gerar uma pagina HTML com ações de um formulário HTML5. Abaixo uma lista de leitura complementar

Chamando um formulário

A forma padrão de chamar um formulário é via menu

Porém é possível chamar um formulário diretamente via URL como no exemplo abaixo http://localhost/formDin/appteste/index.php?modulo=pedido

ou

http://localhost/formDin/appteste/index.php?modulo=modulos/pedido.php

Lembrando a variável modulo segue o mesmo principio do parâmetro strUrl na criação do menu. Veja mais detalhes em O quarto parâmetro strUrl

Melhorando aplicação

alterar index.php

Edite o arquivo index.php, altere para o conteúdo abaixo

<?php
require_once('../base/classes/webform/TApplication.class.php');
require_once('classes/autoload_hw.php');

$app = new TApplication();
$app->setTitle('Hello');
$app->setSigla('hw');
$app->setVersionSystem('0.0.0');
$app->setLoginInfo('Bem-vindo');
$app->setMainMenuFile('includes/menu.php');
$app->run();
?>

incluir autoload_hw.php

  1. crie o diretório classes
  2. crie o arquivo autoload_hw.php e coloque o arquivo abaixo
<?php
if ( !function_exists( 'hw_autoload') ) {
    function hw_autoload( $class_name )	{
        require_once $class_name . '.class.php';
    }
    spl_autoload_register('hw_autoload');
}

No index foi incluindo o autoload para classes de negócios que ficam na pasta classes. O uso do autoloado evita escrever varias linhas de includente ou require.

Mais informações sobre o autoload

incluir Tb_pedido.class.php

  1. crie o arquivo Tb_pedido.class.php na pasta classes e coloque o conteúdo abaixo
<?php
class Tb_pedido {    
    public function __construct(){
    }
    //--------------------------------------------------------------------------------
    public static function selectAll( $orderBy = null, $where = null ){
        $result = Tb_pedidoDAO::selectAll( $orderBy, $where );
        return $result;
    }
    //--------------------------------------------------------------------------------
    public static function selectById( $id ){
        $result = Tb_pedidoDAO::selectById( $id );
        return $result;
    }
    //--------------------------------------------------------------------------------
    public static function save( Tb_pedidoVO $objVo ){
        $result = null;
        if( $objVo->getId_pedido() ) {
            $result = Tb_pedidoDAO::update( $objVo );
        } else {
            $result = Tb_pedidoDAO::insert( $objVo );
        }
        return $result;
    }
    //--------------------------------------------------------------------------------
    public static function delete( $id ){
        $result = Tb_pedidoDAO::delete( $id );
        return $result;
    }    
}

editar arquivo pedido.php

Edite o arquivo pedido.php, substitua o conteúdo pelo que está logo abaixo.

<?php

//d($_REQUEST);
$primaryKey = 'ID_PEDIDO';
$frm = new TForm('Cadastro de Pedidos');
$frm->setFlat(true);
$frm->setMaximize(true);

$frm->addHiddenField($primaryKey); // coluna chave da tabela
$frm->addTextField('NOME_COMPRADOR', 'Nome do Comprador', 50, false, 50);
$frm->addDateField('DATA_PEDIDO', 'Data do Pedido');
$listPagamento = array(1=>'Dinheiro',2=>'Cheque',3=>'Cartão');
$frm->addSelectField('FORMA_PAGAMENTO', 'Pagamento',false,$listPagamento);


$frm->addButton('Salvar', null, null, null, null, true, false);
$frm->addButton('Limpar', null, 'Limpar', null, null, false, false);

$acao = isset($acao) ? $acao : null;
switch( $acao ) {
    case 'Salvar':
        try{
            if ( $frm->validate() ) {
                $vo = new Tb_pedidoVO();
                $frm->setVo( $vo );
                $resultado = Tb_pedido::save( $vo );
                if($resultado==1) {
                    $frm->setMessage('Registro gravado com sucesso!!!');
                    $frm->clearFields();
                }else{
                    $frm->setMessage($resultado);
                }
            }
        }
        catch (DomainException $e) {
            $frm->setMessage( $e->getMessage() );
        }
        catch (Exception $e) {
            MessageHelper::logRecord($e);
            $frm->setMessage( $e->getMessage() );
        }
        break;
        //--------------------------------------------------------------------------------
    case 'Limpar':
        $frm->clearFields();
        break;
        //--------------------------------------------------------------------------------
    case 'gd_excluir':
        try{
            $id = $frm->get( $primaryKey ) ;
            $resultado = Tb_pedido::delete( $id );;
            if($resultado==1) {
                $frm->setMessage('Registro excluido com sucesso!!!');
                $frm->clearFields();
            }else{
                $frm->clearFields();
                $frm->setMessage($resultado);
            }
        }
        catch (DomainException $e) {
            $frm->setMessage( $e->getMessage() );
        }
        catch (Exception $e) {
            MessageHelper::logRecord($e);
            $frm->setMessage( $e->getMessage() );
        }
        break;
}

$dados = Tb_pedido::selectAll( $primaryKey, null );
$mixUpdateFields = $primaryKey.'|'.$primaryKey
                 .',NOME_COMPRADOR|NOME_COMPRADOR'
                 .',DATA_PEDIDO|DATA_PEDIDO'
                 .',FORMA_PAGAMENTO|FORMA_PAGAMENTO';
$gride = new TGrid('gd' // id do gride
                  ,'Lista de Pedidos' // titulo do gride
                  , $dados   // array de dados
                  , null     // altura do gride
                  , null     // largura do gride
                  , $primaryKey // chave primaria
                  , $mixUpdateFields // atulização dos campos
                  );    
        
$gride->addColumn($primaryKey, 'id Pedido');
$gride->addColumn('NOME_COMPRADOR','Nome do Comprador');
$gride->addColumn('DATA_PEDIDO', 'Data');
$gride->addColumn('FORMA_PAGAMENTO', 'Pagamento');

$frm->addHtmlField('gride', $gride);
    

$frm->show();
?>

Entendendo

O Fluxo de chamada

O formDin utiliza architecture pattern MVC

MVC é nada mais que um padrão de arquitetura de software, separando sua aplicação em 3 camadas. A camada de interação do usuário(view), a camada de manipulação dos dados(model) e a camada de controle(controller). fonte: https://tableless.com.br/mvc-afinal-e-o-que/

Na imagem é possível ver o fluxo dos dados da tela, passando pela classes de regras de negocio até chegar no banco de dados e voltar para a tela. Fluxo formDin

Como é criado um formulário ?

Todo formulário é criado na linha

$frm = new TForm('Cadastro de Pedidos');

E termina com

$frm->show();
?>

Entre esse dois pontos deve ser incluído todo o restante: campo, botões, grids, treeview e etc. Se tiver JavaScript pode ser incluir no final depois do fecha PHP logo depois do $frm->show();

A linhas abaixo mostram duas propriedades do formulário

$frm->setFlat(true);  //Layout Flat
$frm->setMaximize(true); //Permite maximizar

Um formulário padrão tem a estrutura

  • Declaração do TForm
  • Campos do formulário.
  • Botões
  • Switch de ações
  • Grid
  • JavaScript pequeno

Campos do Formulário

Todos os campos e elementos da tela herdam de TElement. anatomy-of-an-html-element

https://github.com/jetphp/jetphp/issues/15

Ações no form

Por padrão um form irá executar uma ação com um POST pegando cada campo e enviado para o cabeçalho HTTP. No caso do PHP essa informação pode ser resgatada no $_POST ou $_RESQUEST. É recomendável utilizar sempre o $_RESQUEST pois nessa variável vem os valores enviados via GET.

Por padrão toda ação acontece em função de um botão

$frm->addButton('Salvar', null, null, null, null, true, false);

Processando ações dos botões

As ações são processadas no switch( $acao ), abaixo temos um exemplo típico com as ações mais comuns: Salvar, Limpar, Excluir. Se for uma ação Salvar existem dois métodos que auxiliam muito.

$frm->validate()

O Validate retorna TRUE se todos os campos obrigatórios foram preenchidos, se não retorna FALSE e gera uma mensagem de alerta.

$frm->setVo( $vo );

Se VO irá pegar cada campo da tela e colocar no atributo do objeto VO correspondente. **ATENÇÃO ** o setVo só irá funcionar se os nomes dos campos da tela forem iguais aos atributos do VO.

$acao = isset($acao) ? $acao : null;
switch( $acao ) {
    case 'Salvar':
        try{
            if ( $frm->validate() ) {
                $vo = new Tb_pedidoVO();
                $frm->setVo( $vo );
                $resultado = Tb_pedido::save( $vo );
                if($resultado==1) {
                    $frm->setMessage('Registro gravado com sucesso!!!');
                    $frm->clearFields();
                }else{
                    $frm->setMessage($resultado);
                }
            }
        }
        catch (DomainException $e) {
            $frm->setMessage( $e->getMessage() );
        }
        catch (Exception $e) {
            MessageHelper::logRecord($e);
            $frm->setMessage( $e->getMessage() );
        }
        break;
        //--------------------------------------------------------------------------------
    case 'Limpar':
        $frm->clearFields();
        break;
        //--------------------------------------------------------------------------------
    case 'gd_excluir':
        try{
            $id = $frm->get( $primaryKey ) ;
            $resultado = Tb_pedido::delete( $id );;
            if($resultado==1) {
                $frm->setMessage('Registro excluido com sucesso!!!');
                $frm->clearFields();
            }else{
                $frm->clearFields();
                $frm->setMessage($resultado);
            }
        }
        catch (DomainException $e) {
            $frm->setMessage( $e->getMessage() );
        }
        catch (Exception $e) {
            MessageHelper::logRecord($e);
            $frm->setMessage( $e->getMessage() );
        }
        break;
}

Ações do grid.

Parece estranho falar da grid no capitulo sobre o formulário porém para o correto entendimento da grid é necessário o entendimento do formulário.

Assim como os botões do formulário os botões do Grid, por padrão fazem um POST na pagina. Setando nos campos os valores informados no $mixUpdateFields Grid

O Exemplo abaixo é parte do código da tela pedido do exemplo 2.5.

O $mixUpdateFields faz uma relação entre o nome da coluna que vem do banco com o nome do campo na tela. Esses nomes podem ser os mesmo ou não.

$mixUpdateFields = $primaryKey.'|'.$primaryKey
				.',IDPESSOA|IDPESSOA'
				.',IDTIPO_PAGAMENTO|IDTIPO_PAGAMENTO'
				.',DAT_PEDIDO|DAT_PEDIDO'
				;
$gride = new TGrid( 'gd'                        // id do gride
				   ,'Gride with SQL Pagination' // titulo do gride
				   );
$gride->addKeyField( $primaryKey ); // chave primaria
$gride->setData( $dados ); // array de dados
$gride->setRealTotalRowsSqlPaginator( $realTotalRowsSqlPaginator );
$gride->setMaxRows( $maxRows );
$gride->setUpdateFields($mixUpdateFields);

Mais uma vez : No momento que usuário clicar em um botão do grid os valores informados no $mixUpdateFields serão setados nos campos do form e depois vai cair no switch( $acao )

Da tela ao banco

Durante o desenvolvimento e manutenção de sistemas é importante saber qual tela o usuário estava usando. Uma das formas é olhar no canto direito inferior da tela onde a seta está apontando. Screen Shot Appteste pedido

Uma vez com o código aberto deve ser observado no switch de ações qual método é chamado.

Próxima etapa ?

12 - Relatórios em PDF