Avoid many requests in Select

Asked

Viewed 50 times

0

I would like to know some alternative to block excess requests with Select combo box from the following code:

    //Input Cascata Estado / Cidade
$("select[name='estado_id']").change(function(){
var estado_id = $(this).val();
var token = $("input[name='_token']").val();
$("select[name='cidade_id'").html('<option value="0">Aguarde...</option>');
    $.ajax({
        url: "{!! route('admin.select.bairro_cidade')!!}",
        method: 'POST',
        data: {estado_id:estado_id, _token:token},
        success: function(data) {
            $("select[name='cidade_id'").html(data.options);
        }
    });
});

For example, when the user is browsing select with the keyboard ARROWS, each time he changes the state will generate an Ajax request, which can generate many requests in a short interval on the page. I tried to use the focusout, but changing the selector to the next one generates the bug of not loading correctly, having to click again on the next select.

1 answer

2


Disable the select that triggers the event change while AJAX is processed and enabled again after AJAX processing. This prevents bottleneck of processing if the user keeps changing the option quickly.

But re-enable select within a callback complete (and not in the success), because if there is an error (e.g., failure to communicate with the server) complete will be executed anyway, returning select.

It is also necessary to store the element that triggered the change in a variable to be able to reference it within the complete:

$("select[name='estado_id']").change(function(){
   var t = this; // armazena o elemento na variável
   t.disabled = true; // desabilita o select
   var estado_id = t.value;
   var token = $("input[name='_token']").val();
   $("select[name='cidade_id'").html('<option value="0">Aguarde...</option>');
    $.ajax({
        url: "{!! route('admin.select.bairro_cidade')!!}",
        method: 'POST',
        data: {estado_id:estado_id, _token:token},
        success: function(data) {
            $("select[name='cidade_id'").html(data.options);
        },
        complete: function(){
           t.disabled = false; // volta a habilitar o select
        }
    });
});

Edit

It would also be interesting to treat possible errors, such as connection, for example. For this use callback error, where you can return the States select to the first option and display a message in the second select:

$("select[name='estado_id']").change(function(){
   var t = this; // armazena o elemento na variável
   var cidades = $("select[name='cidade_id'"); // armazena o select das cidades
   var estado_id = t.value;
   var token = $("input[name='_token']").val();
   t.disabled = true; // desabilita o select
   cidades.html('<option value="0">Aguarde...</option>');
    $.ajax({
        url: "{!! route('admin.select.bairro_cidade')!!}",
        method: 'POST',
        data: {estado_id:estado_id, _token:token},
        success: function(data) {
            cidades.html(data.options);
        },
        complete: function(){
           t.disabled = false; // volta a habilitar o select
        },
        error: function(){
           t.selectedIndex = 0; // volta o select para o primeiro option
           cidades.html("<option value='0'>Houve um problema!</option>"); // coloca um option com uma mensagem
        }
    });
});
  • I tested and did not complete the select of municipalities in this way, I think the idea the timeout may be feasible

  • @Rafaelmeirim I forgot to put data.options in the $("select[name='cidade_id'").html(data.options). Test now that should work.

  • @Rafaelmeirim I will edit the answer with a more complete solution predicting possible errors.

  • Very good, I made some changes to be displayed correctly and in complete I gave a Focus in the id state to enable the arrows again (if the user selects by this method)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.