Lançado Adianti Framework 7.6!
Clique aqui para saber mais
Problema com TCombo::Reload quando a lista passada é grande Pessoal estou com o seguinte problema, tenho uma lista de estados usando o TUniqueSearch e configurei o setChangeAction para atualizar a lista de Cidades que também usa o TUniqueSearch. Para atualizar esta lista de cidades estou usando uma API do IBGE que retorna a lista de cidades, quando o retorno da API retornam poucas cidades meu código funciona e a lista do TUniqueSearch funciona quando re...
EA
Problema com TCombo::Reload quando a lista passada é grande  
Pessoal estou com o seguinte problema, tenho uma lista de estados usando o TUniqueSearch e configurei o setChangeAction para atualizar a lista de Cidades que também usa o TUniqueSearch.
Para atualizar esta lista de cidades estou usando uma API do IBGE que retorna a lista de cidades, quando o retorno da API retornam poucas cidades meu código funciona e a lista do TUniqueSearch funciona quando retornam muitos dados não.
Exemplo:
- Funciona: https://servicodados.ibge.gov.br/api/v1/localidades/estados/AC/municipios
- Não funciona: https://servicodados.ibge.gov.br/api/v1/localidades/estados/RS/municipios

Meu código que busca a lista de cidades está assim:

public static function getCidades($Uf) { try { $retorno = json_decode(file_get_contents("https://servicodados.ibge.gov.br/api/v1/localidades/estados/{$Uf}/municipios")); if (isset($retorno->erro)) { $retorno->mensagem = "Cidades: Dados não encontrados!"; } $ret = []; foreach ($retorno as $obj) { $ret[$obj->nome] = $obj->nome; } return $ret; } catch (Exception $e) { echo 'Error: ' . $e->getMessage(); } }


Aqui é o código do setChangeAction
public static function onChangeUf($param) { $cidades = ConsultaCepService::getCidades($param['end_1_uf']); TCombo::reload('Transportadora_form', 'end_1_cidade', $cidades); }


Aqui está a definição dos meus campos no Create
$ufs = ConsultaCepService::getUfs(); $end_1_uf = new TUniqueSearch('end_1_uf'); $end_1_uf->addValidation('UF', new TRequiredValidator ); $end_1_uf->addItems( $ufs ); $end_1_uf->setChangeAction(new TAction(array($this, 'onChangeUf'))); $end_1_cidade = new TUniqueSearch('end_1_cidade'); $end_1_cidade->addValidation('Cidade', new TRequiredValidator );


Quando seleciono o estado Acre a lista é carregada, quando seleciono Rio Grande do Sul ou São Paulo, por exemplo, retorna o erro abaixo no console:

VM4409:1
Uncaught SyntaxError: missing ) after argument list
at b (jquery.min.js?afver=722:2)
at Ie (jquery.min.js?afver=722:2)
at k.fn.init.append (jquery.min.js?afver=722:2)
at __adianti_parse_html (adianti.min.js?afver=722:formatted:638)
at Object.<anonymous> (adianti.min.js?afver=722:formatted:617)
at c (jquery.min.js?afver=722:2)
at Object.fireWith [as resolveWith] (jquery.min.js?afver=722:2)
at l (jquery.min.js?afver=722:2)
at XMLHttpRequest.<anonymous> (jquery.min.js?afver=722:2)

Curso completo Meu Negócio Pronto
Use para si, ou transforme em um negócio: Inclui aulas e códigos-fontes
Gestor de conteúdo (SITE) + Loja Virtual (E-Commerce) + Emissor de Notas para infoprodutos


Meu negócio pronto Quero me inscrever agora!

Comentários (13)


HD

Bom dia Edson...

Eu reproduzi aqui sua dinâmica e rodou perfeitamente... porém eu utilizei o Guzzle para fazer as requisições:

  1. <?php 
  2.         $form = new Adianti\Wrapper\BootstrapFormBuilder('test_states');
  3.         $estado = new TUniqueSearch('estado');
  4.         $client = new GuzzleHttp\Client();
  5.         $res $client->get('https://servicodados.ibge.gov.br/api/v1/localidades/estados');
  6.         $estados = [];
  7.         foreach (json_decode($res->getBody()->getContents()) as $key => $value) {
  8.             $estados[$value->sigla] = $value->nome;
  9.         }
  10.         $estado->addItems($estados);
  11.         $cidade = new TCombo('cidade');
  12.         $form->addFields([$estado], [$cidade]);
  13.         $estado->setChangeAction(new TAction([__CLASS__'changeEstado'], $param));
  14.      // método changeEstado
  15.      public static function changeEstado$param )
  16.      {
  17.         $estado $param['estado'];
  18.         $client = new GuzzleHttp\Client();
  19.         $res $client->get('https://servicodados.ibge.gov.br/api/v1/localidades/estados/'.$estado.'/municipios');
  20.         $cidades = [];
  21.         foreach (json_decode($res->getBody()->getContents()) as $key => $value) {
  22.             $cidades[$value->id] = $value->nome;
  23.         }
  24.         TCombo::reload('test_states''cidade'$cidades);
  25.      }
  26. ?>
EA

Hélquisson, Obrigado funcionou perfeitamente.
Obrigado
EA

Como faço para recarregar a lista de cidades quando ocorre um erro no salvar os dados?
Por exemplo faltou preencher um campo obrigatório e apresentou mensagem de erro na tela, então a lista de cidades e o campo de cidade é apagado e não estou sabendo em que momento fazer o carregamento novamente.
HD

Dentro da Exceção você recupera o valor do campo estado e dá outro reload no campo de cidades!

Tenta assim:

  1. <?php
  2.  catch (Exception $e// in case of exception
  3.         {
  4.             new TMessage('error'$e->getMessage()); // shows the exception error message
  5.             $data $this->form->getData();
  6.             $this->form->setData$data ); // keep form data
  7.             TTransaction::rollback(); // undo all pending operations
  8.             $uf $data->estado;
  9.             $client = new GuzzleHttp\Client();
  10.             $res $client->get('https://servicodados.ibge.gov.br/api/v1/localidades/estados/'.$uf.'/municipios');
  11.             $cidades = [];
  12.             foreach (json_decode($res->getBody()->getContents()) as $key => $value) {
  13.                 $cidades[$value->id] = $value->nome;
  14.             }
  15.             TCombo::reload('test_states''cidade'$cidades);
  16.         }
  17. ?>
EA

Entendi, mas estou usando o TStandardForm que por sua vez usa o AdiantiStandardFormTrait e dentro deste último tem o onSave com o tratamento de exceção.
Como faço para fazer usar isto?
Vou ter que trazer pra minha classe este onSave?
HD

Certo... eu nunca usei o TStandardForm... mas acredito que você pode mover o método onSave para sua classe e mudar o comportamento... ou identificar o método via $param no seu construtor e fazer o reload novamente.
EA

Obrigado pelas dicas, consegui fazer no construtor da seguinte forma.

  1. <?php
  2.         $object $this->form->getData();
  3.         if (!empty($object->end_1_uf)) {
  4.             $cidades ConsultaCepService::getCidades($object->end_1_uf);
  5.             $end_1_cidade->addItems$cidades );
  6.         }
  7.  ?>
HD

Show de bola, Edson!
EA

Só falta uma única coisa para terminar, quando vou editar o registro, no construtor onde coloquei a identificação se o campo cidade possui valor, os campos não veem preenchidos e minha identificação que coloquei antes não funciona e o campo cidade não vem com a lista de cidades carregadas, com isto o campo não fica preenchido com a cidade.
HD

Bom... nesse caso precisa tentar entender o que está acontecendo... comenta o código que você adicionou no construtor... e tenta editar... veja se os outros campos vem preenchidos novamente.
EA

Olá,
Consegui fazer aqui, no botão editar eu aponto para um onEditInterno da minha tela de cadastro, nela eu busco o registro do banco pela chave passada e faço o carregamento da lista de cidades pela UF que está no banco.
Depois disto eu chamo o onEdit definido no AdiantiStandardFormTrait.
HD

Ok... talvez não precisaria do onEditInterno! Que bom que conseguiu!
EA

Pode ser que nem precise, porém foi a única forma que encontrei para fazer funcionar.
Obrigado pelas ajudas