Funcao fire_events TDBCombo dinamico Ola pessoal, Estou tendo um problema com o fire_events dos TDBCombo, Ele esta sendo acionado no evento onEdit de uma classe para carregar 2 combos automaticamente. 1. apos alimentar combo UF ->faz o filtro das cidades daquela uf* 2. apos alimentar a combo CIDADES ->faz o filtro das igrejas daquela cidade* O problema é que se eu der um F5 ele me mostra os dados corretamente ...
RS
Funcao fire_events TDBCombo dinamico  
Ola pessoal,

Estou tendo um problema com o fire_events dos TDBCombo,

Ele esta sendo acionado no evento onEdit de uma classe para carregar 2 combos automaticamente.
1. apos alimentar combo UF
->faz o filtro das cidades daquela uf*
2. apos alimentar a combo CIDADES
->faz o filtro das igrejas daquela cidade*

O problema é que se eu der um F5 ele me mostra os dados corretamente e logo em seguida perde os valores, como se executasse mais de uma vez a trigger

tenho uma outra classe com as mesmas funcoes e mesmo nome de campos que funciona perfeitamente.

segue classe abaixo, se puderem me dar uma ajuda agradeço:
 
  1. <?php
  2. class LideresForm extends TPage
  3. {
  4. use Adianti\Base\AdiantiStandardFormTrait;
  5. protected $form;
  6. public function __construct()
  7. {
  8. parent::__construct();
  9. $this->setDatabase('warriors');
  10. $this->setActiveRecord('Lideres');
  11. $this->form = new BootstrapFormBuilder(__CLASS__.'form');
  12. $this->form->setFormTitle('Cadastro de Líderes');
  13. $this->form->style = 'width:100%';
  14. $id = new TEntry('id');
  15. $nome = new TEntry('nome');
  16. $uf = new TDBCombo('uf', 'warriors', 'Estados', 'uf', '{nome}');
  17. $cidade = new TDBCombo('cidade', 'warriors', 'Cidades', 'id', '{nome}');
  18. $igreja_id = new TDBCombo('igreja_id', 'warriors', 'Igrejas', 'id', 'apelido');
  19. $departamento_id = new TDBCombo('departamento_id', 'warriors', 'Departamentos', 'id', 'descricao');
  20. $fone = new TEntry('fone');
  21. $email = new TEntry('email');
  22. $senha = new TPassword('senha');
  23. $ativo = new TCombo('ativo');
  24. $ativo->addItems(['S'=>'Sim', 'N'=>'Não']);
  25. $id->setEditable(FALSE);
  26. $senha->setEditable(FALSE);
  27. $uf->enableSearch();
  28. $cidade->enableSearch();
  29. $igreja_id->enableSearch();
  30. $uf->setChangeAction(new TAction([$this, 'onChangeUf']));
  31. $cidade->setChangeAction(new TAction([$this, 'onChangeCidade']));
  32. $this->form->addFields([new TLabel('Id')],[$id]);
  33. $this->form->addFields([new TLabel('Nome')],[$nome]);
  34. $this->form->addFields([new TLabel('UF')],[$uf]);
  35. $this->form->addFields([new TLabel('Cidade')],[$cidade]);
  36. $this->form->addFields([new TLabel('Igreja')],[$igreja_id]);
  37. $this->form->addFields([new TLabel('Departamento')],[$departamento_id]);
  38. $this->form->addFields([new TLabel('Fone')],[$fone]);
  39. $this->form->addFields([new TLabel('Email')],[$email]);
  40. $this->form->addFields([new TLabel('Senha')],[$senha]);
  41. $this->form->addFields([new TLabel('Ativo')],[$ativo]);
  42. $this->form->addAction(_t('Save'), new TAction([$this, 'onSave']), 'fa: fa-save green');
  43. $this->form->addAction('Gerar Nova Senha', new TAction([$this, 'onSave'], ['renew'=>true]), 'fa: fa-cogs red');
  44. $this->form->addAction(_t('Back'), new TAction(['LideresList', 'onReload']), 'fa: fa-arrow-circle-left blue');
  45. $container = new TVBox();
  46. $container->style = 'width:100%; overflow-x:auto';
  47. $bread = new TBreadCrumb;
  48. $bread->addHome();
  49. $bread->addItem('Líderes');
  50. $bread->addItem('Cadastro de Líderes', TRUE);
  51. $container->add($bread);
  52. $container->add($this->form);
  53. parent::add($container);
  54. }
  55. public function fire_events($object)
  56. {
  57. TForm::sendData(__CLASS__."form", $object);
  58. }
  59. public function onEdit($param)
  60. {
  61. try
  62. {
  63. if (empty($this->database))
  64. {
  65. throw new Exception(AdiantiCoreTranslator::translate('^1 was not defined. You must call ^2 in ^3', AdiantiCoreTranslator::translate('Database'), 'setDatabase()', AdiantiCoreTranslator::translate('Constructor')));
  66. }
  67. if (empty($this->activeRecord))
  68. {
  69. throw new Exception(AdiantiCoreTranslator::translate('^1 was not defined. You must call ^2 in ^3', 'Active Record', 'setActiveRecord()', AdiantiCoreTranslator::translate('Constructor')));
  70. }
  71. if (isset($param['key']))
  72. {
  73. // get the parameter $key
  74. $key=$param['key'];
  75. // open a transaction with database
  76. TTransaction::open($this->database);
  77. $class = $this->activeRecord;
  78. // instantiates object
  79. $object = new $class($key);
  80. // fill the form with the active record data
  81. $this->form->setData($object);
  82. // close the transaction
  83. TTransaction::close();
  84. $this->fire_events($object); /* aqui executa o evento*/
  85. return $object;
  86. }
  87. else
  88. {
  89. $this->form->clear( true );
  90. }
  91. }
  92. catch (Exception $e) // in case of exception
  93. {
  94. // shows the exception error message
  95. new TMessage('error', $e->getMessage());
  96. // undo all pending operations
  97. TTransaction::rollback();
  98. }
  99. }
  100. public function onSave($param = NULL)
  101. {
  102. try
  103. {
  104. if (empty($this->database))
  105. {
  106. throw new Exception(AdiantiCoreTranslator::translate('^1 was not defined. You must call ^2 in ^3', AdiantiCoreTranslator::translate('Database'), 'setDatabase()', AdiantiCoreTranslator::translate('Constructor')));
  107. }
  108. if (empty($this->activeRecord))
  109. {
  110. throw new Exception(AdiantiCoreTranslator::translate('^1 was not defined. You must call ^2 in ^3', 'Active Record', 'setActiveRecord()', AdiantiCoreTranslator::translate('Constructor')));
  111. }
  112. // open a transaction with database
  113. TTransaction::open($this->database);
  114. // get the form data
  115. $object = $this->form->getData($this->activeRecord);
  116. if (empty($object->senha)||isset($param['renew']))
  117. {
  118. $nova_senha = TUtil::geraSenha(6, FALSE);
  119. $object->senha = md5($nova_senha);
  120. }
  121. else
  122. {
  123. unset($object->senha);
  124. }
  125. // validate data
  126. $this->form->validate();
  127. // stores the object
  128. $object->store();
  129. // fill the form with the active record data
  130. $this->form->setData($object);
  131. //Verifica se o email foi preenchido e faz a validação do usuario vinculado ao líder
  132. if(!empty($object->email))
  133. {
  134. $user = SystemUser::newFromEmail($object->email);
  135. if (empty($user)) //Usuário não existe
  136. {
  137. $user = new SystemUser();
  138. $user->name = $object->nome;
  139. $user->email = $object->email;
  140. $user->login = $object->email;
  141. $user->password = $object->senha;
  142. $user->frontpage_id = 7;
  143. $user->active = 'Y';
  144. $user->store();
  145. $user->addSystemUserGroup(SystemGroup::find(2));
  146. }
  147. else //Usuário já existe
  148. {
  149. //Alterou senha
  150. if ($object->senha)
  151. {
  152. $user->password = $object->senha;
  153. $user->store();
  154. }
  155. }
  156. }
  157. // close the transaction
  158. TTransaction::close();
  159. $this->fire_events($object);
  160. // shows the success message
  161. if (isset($this->useMessages) AND $this->useMessages === false)
  162. {
  163. AdiantiCoreApplication::loadPageURL( $this->afterSaveAction->serialize() );
  164. }
  165. else
  166. {
  167. new TMessage('info', AdiantiCoreTranslator::translate('Record saved'), $this->afterSaveAction);
  168. if (isset($nova_senha)) {$this->form->add(new TAlert('info', 'A senha gerada é: <br>'.$nova_senha));}
  169. }
  170. return $object;
  171. }
  172. catch (Exception $e) // in case of exception
  173. {
  174. // get the form data
  175. $object = $this->form->getData();
  176. // fill the form with the active record data
  177. $this->form->setData($object);
  178. // shows the exception error message
  179. new TMessage('error', $e->getMessage());
  180. // undo all pending operations
  181. TTransaction::rollback();
  182. }
  183. }
  184. public static function onChangeUf($param)
  185. {
  186. $criteria = new TCriteria();
  187. if(!empty($param['key']))
  188. {
  189. $criteria->add(new TFilter('uf','=', $param['key']));
  190. TDBCombo::reloadFromModel(
  191. __CLASS__.'form',
  192. 'cidade',
  193. 'warriors',
  194. 'Cidades',
  195. 'id',
  196. 'nome',
  197. null,
  198. $criteria);
  199. }
  200. else
  201. {
  202. TDBCombo::clearField(__CLASS__.'form', 'cidade');
  203. }
  204. }
  205. public static function onChangeCidade($param)
  206. {
  207. if(!empty($param['key']))
  208. {
  209. $criteria = new TCriteria();
  210. $criteria->add(new TFilter('cidade','=', $param['key']));
  211. TDBCombo::reloadFromModel(
  212. __CLASS__.'form',
  213. 'igreja_id',
  214. 'warriors',
  215. 'Igrejas',
  216. 'id',
  217. '{apelido} {cidade_nome}',
  218. null,
  219. $criteria);
  220. }
  221. else
  222. {
  223. TDBCombo::clearField(__CLASS__.'form', 'igreja_id');
  224. }
  225. }
  226. }
  227. ?>

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)


FC

Na versão 7 foi alterado o método sendData nesse caso passe o false depois do objeto.

 
  1. <?php
  2. public function fire_events($object)
  3. {
  4. TForm::sendData(__CLASS__."form", $object, false, false);
  5. }
  6. ?>
RS

Bom dia Felipe, obrigado pela resposta amigo,

Antes de postar aqui no fórum eu dei uma olhada na função sendData dentro da classe TForm, e fiz esse teste, o caso é que dessa maneira o sistema não faz o TCombo::reload enão tras somente as cidades da UF selecionada na combo UF anterior.

Tenho uma classe na versão 7 tambem que possui as funcoes identicas, inclusive com o mesmo nome dos fields e nome funcao, e nela funciona normalmente ao carregar a pagina,
não consigo entender porque aqui nao funciona, já olhei em tudo, é uma tela muito simplista e um código limpo na medida do possível, porém nao consigo encontrar o Wally rsrs.

Tem mais alguma idéia?
FC

Eu faço um pouco diferente no seu caso vc excuta o setData e o sendData eu acredito que vc não precisa fazer isso basta fazer o TDBCombo::reloadFromModel no onEdit e depois mandar por setData mesmo não testei mas acho que não está preenchendo pq não existe o option quando vc manda para o form.

tenta algo assim para testar.

 
  1. <?php
  2. $criteria = new TCriteria();
  3. $criteria->add(new TFilter('cidade','=', $object->cidade_id));
  4. TDBCombo::reloadFromModel(
  5. __CLASS__.'form',
  6. 'igreja_id',
  7. 'warriors',
  8. 'Igrejas',
  9. 'id',
  10. '{apelido} {cidade_nome}',
  11. null,
  12. $criteria);
  13. $this->form->setData($object);
  14. ?>
RS

Ontem eu fiz esse teste tambem, nesse caso o app entra em loop, ele fica mandando o value e executando a trigger sem parar,

Simplifiquei o codigo pra ficar mais legivel, deixei apenas os componentes que estao afetados.

 
  1. <?php
  2. class LideresForm extends TPage
  3. {
  4. use Adianti\Base\AdiantiStandardFormTrait;
  5. protected $form;
  6. public function __construct()
  7. {
  8. parent::__construct();
  9. $this->setDatabase('warriors');
  10. $this->setActiveRecord('Lideres');
  11. $this->form = new BootstrapFormBuilder(__CLASS__.'form');
  12. $this->form->setFormTitle('Cadastro de Líderes');
  13. $this->form->style = 'width:100%';
  14. $uf = new TDBCombo('uf', 'warriors', 'Estados', 'uf', 'nome');
  15. $cidade = new TDBCombo('cidade', 'warriors', 'Cidades', 'id', 'nome');
  16. $igreja_id = new TDBCombo('igreja_id', 'warriors', 'Igrejas', 'id', 'apelido');
  17. $uf->setChangeAction(new TAction([$this, 'onChangeUf']));
  18. $cidade->setChangeAction(new TAction([$this, 'onChangeCidade']));
  19. $this->form->addFields([new TLabel('UF')],[$uf]);
  20. $this->form->addFields([new TLabel('Cidade')],[$cidade]);
  21. $this->form->addFields([new TLabel('Igreja')],[$igreja_id]);
  22. $this->form->addAction(_t('Save'), new TAction([$this, 'onSave']), 'fa: fa-save green');
  23. $this->form->addAction(_t('Back'), new TAction(['LideresList', 'onReload']), 'fa: fa-arrow-circle-left blue');
  24. $container = new TVBox();
  25. $container->style = 'width:100%; overflow-x:auto';
  26. $bread = new TBreadCrumb;
  27. $bread->addHome();
  28. $bread->addItem('Líderes');
  29. $bread->addItem('Cadastro de Líderes', TRUE);
  30. $container->add($bread);
  31. $container->add($this->form);
  32. parent::add($container);
  33. }
  34. public function fire_events($object)
  35. {
  36. TForm::sendData(__CLASS__."form", $object);
  37. }
  38. public function onEdit($param)
  39. {
  40. try
  41. {
  42. if (empty($this->database))
  43. {
  44. throw new Exception(AdiantiCoreTranslator::translate('^1 was not defined. You must call ^2 in ^3',
  45. AdiantiCoreTranslator::translate('Database'), 'setDatabase()', AdiantiCoreTranslator::translate('Constructor')));
  46. }
  47. if (empty($this->activeRecord))
  48. {
  49. throw new Exception(AdiantiCoreTranslator::translate('^1 was not defined. You must call ^2 in ^3',
  50. 'Active Record', 'setActiveRecord()', AdiantiCoreTranslator::translate('Constructor')));
  51. }
  52. if (isset($param['key']))
  53. {
  54. // get the parameter $key
  55. $key=$param['key'];
  56. // open a transaction with database
  57. TTransaction::open($this->database);
  58. $class = $this->activeRecord;
  59. // instantiates object
  60. $object = new $class($key);
  61. // fill the form with the active record data
  62. $this->form->setData($object);
  63. // close the transaction
  64. TTransaction::close();
  65. $this->fire_events($object);
  66. return $object;
  67. }
  68. else
  69. {
  70. $this->form->clear( true );
  71. }
  72. }
  73. catch (Exception $e) // in case of exception
  74. {
  75. // shows the exception error message
  76. new TMessage('error', $e->getMessage());
  77. // undo all pending operations
  78. TTransaction::rollback();
  79. }
  80. }
  81. public static function onChangeUf($param)
  82. {
  83. $criteria = new TCriteria();
  84. if(!empty($param['key']))
  85. {
  86. $criteria = new TCriteria();
  87. $criteria->add(new TFilter('uf','=', $param['key']));
  88. TDBCombo::reloadFromModel(
  89. __CLASS__.'form',
  90. 'cidade',
  91. 'warriors',
  92. 'Cidades',
  93. 'id',
  94. 'nome',
  95. null,
  96. $criteria);
  97. }
  98. else
  99. {
  100. TDBCombo::clearField(__CLASS__.'form', 'cidade');
  101. }
  102. }
  103. public static function onChangeCidade($param)
  104. {
  105. if(!empty($param['key']))
  106. {
  107. $criteria = new TCriteria();
  108. $criteria->add(new TFilter('cidade','=', $param['key']));
  109. TDBCombo::reloadFromModel(
  110. __CLASS__.'form',
  111. 'igreja_id',
  112. 'warriors',
  113. 'Igrejas',
  114. 'id',
  115. 'apelido',
  116. null,
  117. $criteria);
  118. }
  119. else
  120. {
  121. TDBCombo::clearField(__CLASS__.'form', 'igreja_id');
  122. }
  123. }
  124. }
  125. ?>

FC

Abra o inspecionar vá na aba network e depois execute o onEdit e veja o que ele está executando.
RS

Pelo que vi, esta executando as triggers fora de ordem..

Na classe que funciona normalmente executa:
1. engine.php?class=InscricoesForm&method=onEdit&key=1&id=1 (preenche todo Formulario e preenche os TDBCombo sem filtros indicando o "Selected" correto)
2. engine.php?class=InscricoesForm&method=onChangeUf&static=1&static=1 (tras apenas cidades de acordo com TDBCombo UF)
3. engine.php?class=InscricoesForm&method=onChangeCidade&static=1&static=1 (somente fazendo um clear_TDBCombo IGREJA_ID)
4. engine.php?class=InscricoesForm&method=onChangeCidade&static=1&static=1 (tras apenas as igrejas de acordo com TDBCombo CIDADE)

Já na classe que com problema:
1. engine.php?class=LideresForm&method=onEdit&key=1&id=1 (preenche todo Formulario e preenche os TDBCombo sem filtros indicando o "Selected" correto)
2. engine.php?class=LideresForm&method=onChangeCidade&static=1&static=1 (tras apenas as igrejas de acordo com TDBCombo CIDADE) /*mais ainda nao passou a CIDADE*/
3. engine.php?class=LideresForm&method=onChangeUf&static=1&static=1 (tras apenas cidades de acordo com TDBCombo UF)
4. engine.php?class=LideresForm&method=onChangeCidade&static=1&static=1 (somente fazendo um clear_TDBCombo IGREJA_ID)

Resumindo esta executando as ChangeActions fora de ordem, há como resolver isso?
RS

Felipe Cortez,

descobri o problema e você não vai acreditar,

analisando com sua dica da aba network, e com esses resultados que coloquei, comecei a filosofar aqui,

fui no TRecord que funciona e a ordem estava:
parent::addAttribute('uf');
parent::addAttribute('cidade');
parent::addAttribute('igreja_id');

ja no TRecord que não funciona e a ordem estava errada:
parent::addAttribute('cidade');
parent::addAttribute('uf');
parent::addAttribute('igreja_id');

mudei, salvei e não funcionou, mais não desisti,

Fui na tabela do Mysql.. mudei lá também e pra minha surpresa funcionou...

Ou seja, as ChangeActions executam de acordo com a ordem dos campos na tabela do banco de dados.

Não sei se voce ja sabia dessa condição (eu não sabia), mais fica o conhecimento,

Muito obrigado pelo apoio,

FC

www.adianti.com.br/forum/pt/view_5093?minha-aplicacao-esta-com-erro-


Conselho, revise seu código. Não faz sentido ter duas funções de envio de dados para o form.

Boa sorte !!!
RS

Faz sentido sua observação, eu segui o conselho do tutor:

www.adianti.com.br/framework_files/tutor/index.php?class=FormHierarc

Observei que lá tem o setData no metodo onEdit e o sendData no fire_events,

Obrigado pelo apoio.