Executando verificação de segurança...
1

[AJUDA] Requisições se multiplicando a cada interação com input

Olá, estou tendo dificuldade com requisições que se multiplicam indesejadamente e nao consegui uma solução até o momento.

Acontece que, possuo um select html que ao ser escolhida um option ele efetua uma requisição ao backend e retorna os valores do db nos input abaixo do formulário, até aí tudo certo, a consulta está sendo executada e retornada de maneira correta, porem a cada troca de option desse select sem recarregar a página as requisições são multiplicadas, ex: quando seleciono pela primeira vez, efetua 1 vez a requisição, ao selecionar novamente a requisição é feita 2 vezes seguidas, e isso vai escalando, testei alterar o select 9 vezes sequidas e a mesma requisição é realizada 9 vezes em sequencia com os mesmos parametros, com a mesma resposta, como se existisse uma variavel que a cada interação soma 1 e multiplica a requisição.

aqui uma amostra do select alterado 3 vezes

[15/Mar/2023 23:46:29] "GET /propriedades/atualiza_propriedade/17/ HTTP/1.1" 200 102
[15/Mar/2023 23:46:32] "GET /propriedades/atualiza_propriedade/20/ HTTP/1.1" 200 108
[15/Mar/2023 23:46:32] "GET /propriedades/atualiza_propriedade/20/ HTTP/1.1" 200 108
[15/Mar/2023 23:46:35] "GET /propriedades/atualiza_propriedade/22/ HTTP/1.1" 200 136
[15/Mar/2023 23:46:35] "GET /propriedades/atualiza_propriedade/22/ HTTP/1.1" 200 136
[15/Mar/2023 23:46:35] "GET /propriedades/atualiza_propriedade/22/ HTTP/1.1" 200 136

função js que realiza a consulta:

  $(document).on('change', '#id_propriedade', function () {
    var propriedade_id = $(this).val();
    $.ajax({
      url: '/propriedades/atualiza_propriedade/' + propriedade_id + '/',
      success: function (dados) {
        $('#id_nome').val(dados.nome);
        $('#id_area').val(dados.area);
        $('#id_ie').val(dados.ie);
        $("#id_uf option").each(function () {
          if ($(this).text() == dados.uf) {
            $(this).prop("selected", true);
            }
          });
        $("#id_municipio").empty();
        $("#id_municipio").append($('<option>', {
          value: dados.municipio,
          text: dados.municipio
        })); 
      }        
    });
  });
   
}```
Carregando publicação patrocinada...
2

Cara, erro simples.

$(document).on('change', '#id_propriedade', function () {
    // other things here ...
})

Você está falando "Documento, para cada alteração do formulário, faça a requisição".
E na parte

$("#id_uf option").each(function () {
    if ($(this).text() == dados.uf) {
        $(this).prop("selected", true);
    }
});

Praticamente pra cada option você tá também fazendo uma outra interação. Provavelmente deve ser aqui que está sendo o seu "multiplicador" de requests.

Sei que falei que é um erro simples, mas comecei meu dia lendo e-mails, não vou mexer com código tão cedo kkkk

E outra cara, larga o chatGPT. Tem que ler o próprio código as vezes amigo!
Fonte: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event

TLDR: Alterar o selet dispara o evento change

2

Kkk, coitado dos iniciantes.
Quando eles perguntam mandam ir no Google ou ChatGPT, se mencionam uns dos dois dizem: "...larga o chatGPT. Tem que ler o próprio código...".

2

O problema é que não adianta só pesquisar e usar o primeiro código que funcionou. Tem que entender o que está acontecendo e saber adaptar pro seu caso.

Mais importante que saber onde pesquisar, é saber como pesquisar e o que fazer com os resultados. Mas hoje tem muita gente que só faz o primeiro.

No caso do ChatGPT é pior, pq muitas vezes ele dá um código errado, ou um que "funciona" (esse é pior, porque dá a falsa sensação de ser bom e correto). Já vi vários casos que ele colocou comandos nada a ver no meio, ou código inútil que não fazia nenhuma diferença.

Sempre foi importante não seguir cegamente qualquer coisa que vc vê na internet, e hoje isso se tornou mais importante ainda.

0

Tenta assim:

$(document).ready(function() {
  $('#id_propriedade').on('change', function() {
    
	var propriedade_id = $(this).val();
    $.ajax({
      url: '/propriedades/atualiza_propriedade/' + propriedade_id + '/',
      success: function (dados) {
        $('#id_nome').val(dados.nome);
        $('#id_area').val(dados.area);
        $('#id_ie').val(dados.ie);
        $("#id_uf option").each(function () {
          if ($(this).text() == dados.uf) {
            $(this).prop("selected", true);
            }
          });
        $("#id_municipio").empty();
        $("#id_municipio").append($('<option>', {
          value: dados.municipio,
          text: dados.municipio
        })); 
      }        
    });	    
  });
});

Verifique também se não há ID duplicado.

1

Obrigado, porém não resolveu, oque alterou é que, na primeira seleção a request nao é realizada, na segunda realiza 1 vez, na terceira, 2 e assim por diante.

1

Sei que aparentemente já resolveu, mas estava pensando também, se não está ocorrendo problemas de propagação de evento. E seria interessante usar: event.stopPropagation(); e ver esse assunto.

1
0

chatGPT nao conseguiu resolver essa questão, porem ao realizar o mesmo prompt no plus ele deu a resposta que acabou de me salvar.

  $(document).off('change', '#id_propriedade');
  $(document).on('change', '#id_propriedade', function () {
    var propriedade_id = $(this).val();
    $.ajax({
      url: '/propriedades/atualiza_propriedade/' + propriedade_id + '/',
      success: function (dados) {
        $('#id_nome').val(dados.nome);
        $('#id_area').val(dados.area);
        $('#id_ie').val(dados.ie);
        $("#id_uf option").each(function () {
          if ($(this).text() == dados.uf) {
            $(this).prop("selected", true);
          }
        });
        $("#id_municipio").empty();
        $("#id_municipio").append($('<option>', {
          value: dados.municipio,
          text: dados.municipio
        }));
        var talhoes = dados.talhao.replace(/[\[\]']+/g, '').split(',');
        var mainInput = document.querySelector('input[name="main-input"]');
        talhoes.forEach(function (talhao) {
          mainInput.value = talhao + ',';
          triggerInputEvent(mainInput);
        });
      }      
    });    
  });  
}

a inclusão dessa linha $(document).off('change', '#id_propriedade'); no inicio resolveu o problema.

1

Seria interessante vc colocar o HTML e um exemplo do JSON retornado pela URL. Pois ficar removendo e adicionando o evento toda hora não me parece a melhor alternativa.

Se tivermos mais informações, de repente dá até pra sugerir outra solução.

1

ChatGPT ajuda bastante o aprendizado, estou na caminhada a pouco tempo e codando coisas um pouco especificas então acaba que é complicado achar conteudo e pessoas dispostas a ajudar, porem sempre tento entender, tentei muitas coisas antes de apelar a isso, mas vamos lá, apesar de eu estar muito no inicio de JS, acredito que voces possam me ajudar a melhorar e aos poucos vou me desligando no GPT.

HTML:

<form class="row g-3" action="/propriedades/atualiza_propriedade/" method="POST"><input type="hidden" name="csrfmiddlewaretoken" value="">        
        <div class="col-md-12">
            <label class="lbl-cadcli" for="">Propriedade</label>
            <select name="propriedade" class="form-control form-control upper" onchange="busca_propriedade()" required="" id="id_propriedade">
              <option value="" selected="">---------</option>
              <option value="17">FAZENDA TESTE</option>
              <option value="18">FAZENDA TESTE2</option>
              <option value="19">FAZENDA TESTE3</option>
            </select>
        </div>
</form>

VIEW:

def busca_propriedade(request, propriedade_id):
    propriedade = Propriedade.objects.get(pk=propriedade_id)
    dados = {
        'nome': propriedade.nome,
        'area': propriedade.area,
        'ie': propriedade.ie,
        'uf': propriedade.uf,
        'municipio': propriedade.municipio,
        'talhao': propriedade.talhao,
        'id': propriedade.proptoken,
    }
    return JsonResponse(dados)

FORMS:

class FormAtualizaPropriedade(forms.Form):
    propriedade = forms.ModelChoiceField(queryset=Propriedade.objects.all(), widget=forms.Select(attrs={'class': 'form-control', 'onchange': 'busca_propriedade()'}))

JS: oque eu já mencionei acima.

Acredito ser suficiente, me avise caso precise de mais informação.

1

Esse é o maior perigo do ChatGPT, dar a falsa impressão de estar ajudando.

Pensa assim: se uma pessoa não conhece muito bem um assunto, vc acha que ela é a mais qualificada para avaliar se algo dito sobre esse assunto está certo?

O problema do ChatGPT não são as respostas erradas, são as meio-certas: coisas que parecem corretas (e muitas vezes até "funcionam"), mas se vc se atentar aos detalhes, vai ver coisas esquisitas que não deveriam estar ali. Só que são coisas que um iniciante dificilmente vai perceber, justamente por não ter conhecimento suficiente. Essa é a armadilha.

Não sou contra usá-lo como uma ferramenta que pode agilizar algumas tarefas repetitivas (como toda ferramenta, aliás). Mas sou contra usá-lo cegamente, sem discernimento, aceitando tudo que ele diz sem questionar.

No caso de aprender o básico de programação, tá cheio de tutoriais por aí. Pra JavaScript, por exemplo, tem a MDN (não recomendo a versão em português, as traduções não são boas e algumas tem até erros). Fora os trocentos cursos e roadmaps/"trilhas" por aí (claro, tem muita picaretagem também, infelizmente esse tipo de "curso" aumentou muito).


Sobre o código

Se esse é todo o código, então ainda está incompleto. O JS faz referência a elementos que não estão aí - onde está o elemento HTML com id igual a id_uf, por exemplo?

Esse código usa algum framework? Onde foi definido o objeto Propriedade? Etc

Aliás, se vc vai chamar a URL quando o select mudar, não precisaria ter um action no form: isso serve para indicar a URL chamada quando vc submete o formulário, mas isso não é feito em nenhum momento, então não precisaria. Já o csrfmiddlewaretoken (que pelo nome deve ser para prevenir ataque de CSRF) é uma boa ideia - mas não é usado em lugar algum (a menos que esteja usando algum framework que use ele automaticamente).

É desse tipo de coisa que eu me refiro quando digo que o ChatGPT dá respostas meio-certas. No estágio atual ainda temos que conferir tudo que ele faz (mas alguém sem experiência não vai perceber esses detalhes e vai achar que está tudo "certo").

Enfim, só com isso não dá pra ter certeza absoluta de onde vem o problema. Talvez esteja em outra parte do código (por exemplo, outro lugar modifica o select novamente - como já sugeriram - ou chama a função de novo).

Ou então vc está registrando o evento toda hora (não ficou claro em qual momento on é chamado, mas provavelmente está sendo chamado várias vezes, o que registra o evento de novo e explicaria o problema).

Nesse caso, se quiser que o evento ocorra apenas uma vez, pode usar one em vez de on. Ou então chame on apenas uma vez (ao carregar a página, por exemplo).

Se quiser, sugiro colocar todo o código no GitHub, aí todo mundo consegue testar melhor. Eu só vou ligar o computador na segunda, mas pode ser que alguém te responda antes :-)