Como usar TForm::getFormByName? Olá pessoal do Adianti! Estou com um problema/dúvida: Tenho uma list que tem o form de pesquisa com o nome 'form_search_horario". Nesse form, tenho duas TDBCombos, uma com o nome dos barcos e a outra com a respetiva lotação. Ao fazer a pesquisa, eu quero que só possa pesquisar ou por barco ou por lotação e não por ambos, então criei uma Action para cada uma das combos que cham...
AG
Como usar TForm::getFormByName?  
Olá pessoal do Adianti!

Estou com um problema/dúvida:

Tenho uma list que tem o form de pesquisa com o nome 'form_search_horario".

Nesse form, tenho duas TDBCombos, uma com o nome dos barcos e a outra com a respetiva lotação.

Ao fazer a pesquisa, eu quero que só possa pesquisar ou por barco ou por lotação e não por ambos, então criei uma Action para cada uma das combos que chama o método static onChange, no qual escondo/mostro uma ou outra combo, conforme a escolha da combo no form.

Acontece que ao voltar a mostrar a combo ela aparece com o valor anterior e eu quero que ela aparecça na default option (em branco) só que não estou a conseguir obter o objeto do form com a instrução TForm::getFormByName que me devolve sempre NULL.

Estou a fazer o pedido assim:

$form = TQuickForm::getFormByName($param['_form_name']);


Preciso de saber se estou a fazer algo mal ou se este método getFormByName tem outro tipo de aplicação que não é a que eu estou a pensar?

Agradeço a vossa ajuda!

Um abraço de Portugal!

Abel Gomes

Curso Dominando o Adianti Framework

O material mais completo de treinamento do Framework.
Curso em vídeo aulas + Livro completo + Códigos fontes do projeto ERPHouse.
Conteúdo Atualizado!


Dominando o Adianti Framework Quero me inscrever agora!

Comentários (9)


MC

Abel, boas.

Voce esta querendo saber o nome do form da tela atual ou o form chamador ?


Eu costumo o código abaixo para dar nome aos meus forms, assim não tem erro.

1 - Temos uma variável de ambiente __CLASS__ nela fica gravada o nome da Classe onde esta o form, assim dou o nome ao form
'form_'.__CLASS__.

2 - Ou seja você sempre terá o nome da tela atual. 'form_'.__CLASS__.

3 - Se você utilizou uma tela para chamar outra tela, através de um action, basta colocar um parâmetro conforme abaixo:

->setParameter( 'Form', 'form_'.__CLASS__. );

4 - Na tela chamada guardar o parâmetro numa variável de sessão Ex: abaixo:

 
  1. <?php
  2. public function onNew( $param )
  3. {
  4. $this->form->clear();
  5. $data = $this->form->getData();
  6. TSession::setValue( 'FormX', $param['Form'] );
  7. $this->form->setData( $data );
  8. }
  9. ?>


5 - Para voltar a Tela chamadora ai tem varias formas, vou apenas sitar uma, final de uma função onSave:

 
  1. <?php
  2. $act_dcto = new TAction( array( TSession::getValue('FormX'), 'onEdit' ));
  3. $act_dcto->setParameter( 'key', $object->DCTOID );
  4. new TMessage( 'ok', 'Registro Salvo', $act_dcto );
  5. ?>



Espero ter ajudado,


AG

Oi Marco, muito obrigado pela sua resposta, que vai ajudar-me noutras situações.

Porém, a situação com que eu estava a debater-me era conseguir obter o form dentro de um método estático.

Como eu referi, é uma classe onde eu tenho um form de pesquisa (form_search_Horario) e uma lista de horários por baixo.

Como os campos BARCO e LOTAÇÃO vêm da mesma tabela e estão relacionados, não faz sentido eu pesquisar por exemplo, pelo BARCO: "Titanic" que tem lotação de 3000 lugares e também pesquisar pela LOTAÇÃO: 1500 porque, obviamente não vou obter nenhum registo.

Assim, eu queria esconder o outro campo sempre que preenchesse um deles (pesquiso BARCO e esconde LOTAÇÃO e vice-versa).

Esconder e mostrar eu consigo facilmente com

TQuickForm::hideField($param['_form_name'], $param['field']); e TQuickForm::showField($param['_form_name'], $param['field']);

O meu problema está na situação em que, se depois de eu escolher "Titanic" na combo eu pensar em pesquisar antes pela lotação "1500", quando faço o campo lotação aparecer, ele ainda vem com o último valor que tinha, antes de ter sido escondido. Parece complicado, mas não é... :-)

Eu estava pensando em pegar o objeto do form, e fazer o setDefaultValue à combo antes de ser escondida, para que quando voltasse ao ecrã estivesse em branco.

Resolvi o problema com um script antes do hideField, para onde passo os parametros nome do form e nome da combo e coloco o atributo "selected"

$('form[name='+form_name+'] select[name='+input_name+']' + " option[value='']").attr("selected","selected");

De qualquer forma, gostaria de saber, se dentro de um método estático, existe alguma maneira de obter o objeto do form e trabalhá-lo.

Mais uma vez, muito obrigado pelo seu tempo!

Abel Gomes
MC

Abel, boas

Posta ai o seu codigo ou parte dele para que possamos entender melhor a sua situação.

Abraços
AG

Oi Marco Campos, obrigado pelo teu interesse, mas como disse antes, já resolvi o problema com um script.

Mesmo assim, volto a explicar para quem estiver com o mesmo problema, o que eu queria fazer era o seguinte:

- tenho 2 campos COMBO, ambos relacionados com a mesma tabela e os quais só é lógico procurar por um deles de cada vez
- escolhendo uma opção na COMBO 1, a COMBO 2 desaparece (e vice-versa)
- limpando a escolha da COMBO 1, a COMBO 2 volta a aparecer (e vice-versa)

mas eu queria colocar ativa a opção default da combo antes de a esconder.

Só que, por ter de estar num método estático (onChange) não conseguia ir buscar o objecto form, para depois alterar o default value das combos.

A resposta do Pablo, por email, foi esta:

«Você pode limpar a combo, e logo em seguida adicionar o elemento vazio.
Este método estático somente funciona quando você passa pelo método construtor (ele registra o formulário em uma variável estática).
Em um método estático (ex: change) não passa pelo construtor, logo o formulário não é criado.»

CONCLUSÃO: tem de se alterar os componentes através de Javascript.

A parte do código que pode interessar:

 
  1. <?php
  2. // no construt...
  3. $barco = new TDBCombo('barco', 'viagens', 'Barco', 'barco', '{barco}'); // o 4º parametro é 'barco' e não 'id' porque preciso do nome do barco para a pesquisa
  4. $lotacao = new TDBCombo('lotacao', 'viagens', 'Barco', 'lotacao', '{lotacao}');
  5. // atribuir as ações onChange
  6. $change_barco = new TAction(array($this, 'onChange'));
  7. $change_barco->setParameter('field', 'lotacao');
  8. $barco->setChangeAction($change_barco);
  9. $change_lotacao = new TAction(array($this, 'onChange'));
  10. $change_lotacao->setParameter('field', 'barco');
  11. $lotacao->setChangeAction($change_lotacao);
  12. //..... fim do construct
  13. /** My onChange
  14. * Turn on/off field based on choice from combo
  15. */
  16. public static function onChange($param)
  17. {
  18. $caller = $param['_field_name'];
  19. if ($param[$caller] != ''){
  20. TScript::create( " my_set_default_selected('{$param[_form_name]}', '{$param[field]}'); " );
  21. TQuickForm::hideField($param['_form_name'], $param['field']);
  22. } else {
  23. TQuickForm::showField($param['_form_name'], $param['field']);
  24. }
  25. }
  26. ?>


depois no application.js...

function my_set_default_selected(form_name, input_name){
try {
$('form[name='+form_name+'] select[name='+input_name+']' + " option[value='']").attr("selected","selected");

} catch (e) {
console.log(e);
}
}

Valeu pela ajuda!

Abraço
NR

Abel, você pode usar a função estática sendData da classe TForm:
adianti.com.br/framework_files/tutor/index.php?class=FormInteraction
AG

Nataniel, muito obrigado pela sua resposta, mas no meu caso não consigo, porque estou a usar TDBCombos e não tenho índices (ou não sei como indicar quais) para enviar pelo sendData.

Daí a minha tentativa pelo getFormByName, na esperança de conseguir obter o objecto da TDBCombo e fazer setDefaultOption.

De qualquer forma, a chamada de atenção para sendData vai ser muito útil.

Um abraço e continuação de bom trabalho no fórum.

Abel
NR

Abel, teste o seguinte:
 
  1. <?php
  2. $obj = new stdclass();
  3. $obj->{$param['field']} = '';
  4. TForm::sendData($param['_form_name'],$obj);
  5. ?>
AG

Funciona!!

Muito obrigado, Nataniel, você é um Ás!

Esta solução vai ajudar-me bastante noutras situações deste projeto.

Já agora, perdoando os meus poucos conhecimentos de OOP, dê-me uma justificação para funcionar desta forma e não sem as chavetas { } conforme o exemplo do Tutor que me enviou antes?

E já que estamos numa de troca de impressões entre rookie e pro, na sua opinião, é mais eficiente o script javascript ou esta solução?

MAis uma vez, muito obrigado pelo seu interesse e profissionalismo!

Abraço de Portugal.

Abel
NR

Abel, a questão das chaves é pra evitar ambiguidade. Veja o link abaixo para maiores informações:
php.net/manual/pt_BR/language.variables.variable.php

Sobre a questão de eficiência: internamente a função sendData vai gerar um javascript da mesma maneira, mas como a ideia do Adianti é facilitar o trabalho, aconselho usar as funções do framework ao invés de escrever seu próprio javascript.