0

I have a named helper function to be called from various bootstrap modal windows which are "shopping assistants" on a website I'm working on. All this function does is to initiate an AJAX call to a PHP page which sends back a JSON-encoded array. That is working!

What isn't working is what I thought would be the simplest part of the function: When the function is called it overlays the screen with a spinner (that part is working), and when it's done with the AJAX call it is supposed to hide the spinner. That's the part that isn't working, and I can't figure out why. I think I've been looking at it so long that my brain refuses to work. Here is the code:

function getDetailHandler(prodType, id, element) { // Takes type of product, ID number, and element name)
  $('#spinner').modal('show');
  $.ajax({
    url: '/productHelper.php?type=' + prodType + '&id=' + id,
    type: 'get',
    dataType: 'JSON',
    success: function(response) {
      var len = response.length;
      for (var i = 0; i < len; i++) {
        var id = response[i].id;
        var size = response[i].size;
        var msrp = response[i].msrp;
        var retail = response[i].retail;
        var description = response[i].description;
        var name = response[i].name;

        if (prodType == 2) {
          var tr_str = description;
        } else if (prodType == 3) {
          var tr_str = name + ' added';
        } else {
          var tr_str = size + ' added';
        }
      }
      $('#spinner').modal('hide');
      $('#' + element + '').append(tr_str);

    }
  });
};

The part that's baffling to me is that every other part of the function is working perfectly. It just refuses to hide the modal at the end. Obviously it's my fault somewhere, but I really can't see what I'm doing wrong.

ON EDIT: Here is the calling function:

$('#controlForm').submit(function(e) {
    var sum = 0;
    e.preventDefault();
    $('#addControl').show();
    $('#addControl').append($(document.activeElement).attr('value'));
    $('#addControl').append('<span class="addLightText" style="display:inline";></span><a href="#removeControl" class="removeControl"><i class="fa fa-times-circle fa-2x" name="removeControl" title="Remove Control From Configuration" style="color: Tomato; position: relative;margin-left: 10px; top: 5px;"></i></a>');
    $('#addControl').data('price', $(document.activeElement).attr('value'));
    $('#addControl').attr('data-idnumber', $(document.activeElement).attr('id'));
    $('#addControl').attr('data-price', $(document.activeElement).attr('value'));
    $('#addToCart').append('<input type="hidden" name="controlID" value="' + $(document.activeElement).attr('id') + '" />');
    getDetailHandler(3, $('#addControl').attr('data-idnumber'), 'controlUpdated');
    doSum();

    $('#addControlButtonElement').hide();
    $('#addControlModal').modal('toggle');
});

NOW FIXED I wound up modifying the function to more tightly hook Ajax's start and stop functions using what I found here: https://stackoverflow.com/a/15013828/13114324. It works like a charm!!

Thank you to everyone for your time :)

function getDetailHandler(prodType, id, element) {
    $.ajax({
        url: '/productHelper.php?type='+prodType+'&id='+id,
        type: 'get',
        dataType: 'JSON',
        success: function(response){
            var len = response.length;
                for(var i=0; i<len; i++){
                    var id = response[i].id;
                    var size = response[i].size;
                    var msrp = response[i].msrp;
                    var retail = response[i].retail;
                    var description = response[i].description;
                    var name = response[i].name;

                    if(prodType == 2){
                        var tr_str = description;
                    } else if(prodType == 3) {
                        var tr_str = name + ' added';
                    } else {
                        var tr_str = size + ' added';
                    }
                    $('#'+element+'').append(tr_str);
                }
        }
    });
};

$(document).ajaxSend(function(event, request, settings) {
    $('#spinner').show();
});

$(document).ajaxComplete(function(event, request, settings) {
    $('#spinner').hide();
});
Jimmer631
  • 37
  • 5
  • 1
    Any errors in the console? – Anurag Srivastava Apr 18 '20 at 23:29
  • can you share a working demo please? – Nidhin Joseph Apr 18 '20 at 23:43
  • 1
    Try something, after the function is completed and the spinner is still there, open the console and run `$('#spinner').modal('hide');` and see if that works. – rrk Apr 18 '20 at 23:47
  • I tried the $('#spinner').modal('hide'); function in the console and it worked??? Hehe now I'm really confused. – Jimmer631 Apr 18 '20 at 23:57
  • No errors in the console. I'm going to post a working demo as you requested, Nidhin Joseph. Working on it now :) – Jimmer631 Apr 18 '20 at 23:57
  • Can you try and comment out everything starting with `doSum(); ... etc` ? – skobaljic Apr 19 '20 at 00:01
  • You might also try adding an `error` catch to the ajax and see if it has anything to report. Like `$.ajax( { ..., error: function(e) { console.error(e); } });` – mr rogers Apr 19 '20 at 00:08
  • skobaljic, I commented out the whole calling function (except for the part that calls the getDetailHandler function) and it still failed. Same thing, no console errors. Just no workie :( – Jimmer631 Apr 19 '20 at 00:11

1 Answers1

1

It could be that the show is still transitioning when hide is called. Looking at the Bootstrap modal.js file there is an _isTransitioning guard set in the show function if you're using the 'fade' class. If _isTransitioning is true while hide is called then hide is ignored.

To test this try wrapping the hide in a settimeout function, say 500ms, and see if the hide works.

setTimeout(function(){$('#spinner').modal('hide')}, 500);
Steve M
  • 181
  • 3
  • That is definitely what was happening, and also why there were no errors! I wound up changing the function a little while ago suspecting that to be the case. I'll post my fixed code here in case anyone else has the same problem – Jimmer631 Apr 19 '20 at 04:31