Home > Software engineering >  Ajax beforeSend sometimes doesn't fire to show bootstrap progress bar
Ajax beforeSend sometimes doesn't fire to show bootstrap progress bar

Time:08-27

I have 3 Bootstrap tabs, each with a table showing query results. When the search button is clicked, or a tab is changed, an ajax call is triggered that has a beforeSend function which shows a Bootstrap progress bar. The progress bar always shows the first time I load the page, but then is only intermittent after that. I can't seem to figure out when it shows and when it doesn't. The searches can take 5 or 6 seconds, so it's really necessary to have something for the user to know the search is running.

I saw some threads about async:false causing issues in chrome, but I don't have that set and the issue also shows up in Firefox.

I also saw a thread about having the ajax call wrapped in a document.ready, but this code is in a separate .js file?

OK, the function is long. I'm putting the whole thing in case there's some conflict. I tried commenting out the multiple ajax calls in the success function and just running the one with the beforeSend function but the issue still showed up.

Let me know if you have any ideas to troubleshoot or a potential work around...Thank you!

function submitSearch(method) {
  $("#programCount").html('');
  $("#plotCount").html('');
  $("#treeCount").html('');
  checkdata=validate_input();
  if (checkdata===false) {
     return;
  }
  yearLower= $('#startYr').val();
  yearUpper= $('#endYr').val();
   
  var state=[];
  if(!($('.state_sub_checkbox:checkbox:checked').length === $('.state_sub_checkbox').length)){
      $('.state_sub_checkbox:checkbox:checked').each(function() {
                state.push(this.value);
            });
    }
  var TSN=[];
  var treeSpecies=[];
  if (!($('.species_sub_checkbox:checkbox:checked').length===$('.species_sub_checkbox').length)) {
      $('.species_sub_checkbox:checkbox:checked').each(function() {
 //         species.push(this.value);
          TSN.push(this.value);
          treeSpecies.push($(this).closest("label").text().trim());
      });
  }

  var progList=[];
  var progListNames=[];
  if (!($('.program_sub_checkbox:checkbox:checked').length ===$('.program_sub_checkbox').length)) {
      $('.program_sub_checkbox:checkbox:checked').each(function() {
                progList.push(this.value);
                progListNames.push($(this).closest("label").text().trim());
            }); 
    }    
    
  forestHealth =[];
  if (!($('.FHI_checkbox:checkbox:checked').length===$('.FHI_checkbox').length)) {
      $('.FHI_checkbox:checkbox:checked').each(function() {
          forestHealth.push(this.value);
      });
  }
  crown="";
  if (!($('.crown_checkbox:checkbox:checked').length===$('.crown_checkbox').length)) {
      crown=$('input[name="crown"]:checked').val();
  }
  height=[];
  if (!($('.height_checkbox:checkbox:checked').length===$('.height_checkbox').length)) {
      $('.height_checkbox:checkbox:checked').each(function() {
          height.push(this.value);
      });
  }
  
  tree_status=[];
  if (!($('.tree_status:checkbox:checked').length===$('.tree_status').length)) {
      $('.tree_status:checkbox:checked').each(function() {
          tree_status.push(this.value);
      });      
  }
  
  missingDBH = $('#DBH_missing').prop('checked');
  dbhUpper = $('#endDBH').val();
  dbhLower = $('#startDBH').val();
  missingHeight = $('#height_missing').prop('checked');
  heightUpper = $('#endHeight').val();
  heightLower = $('#startHeight').val();

  var limit=10;  
  var offset="";
  if (method==='ajax_getPrograms') {
      fields = ['pkProgramID','fldName','fldOrganization','fldProgramStartDate','fldProgramEndDate','fldStates'];
      limit=$('#num_results').val();
      offset=$('#program_table_offset').val();
    }
  if (method==='ajax_getPlots') {
      fields = ['programID','lat','long','plotSampleYear','_nefin_plotID', '_nefin_plot_obsID'];  
      limit=$('#num_results_plot').val();
      offset=$('#plot_table_offset').val();      
  }  
  if (method==='ajax_getTrees') {
      fields = ['programID','TSN','treeSpecies','DBH','treeStatus','treeSampleYear','_nefin_plotID','_nefin_plot_obsID','_nefin_treeID','_nefin_tree_obsID'];   
      limit=$('#num_results_tree').val();
      offset=$('#tree_table_offset').val();      
  }
  
  var posturl = baseURL   "data/" method;
  var formData = new FormData();
  if (progList.length>0) {
      formData.append('progList',progList);
      formData.append('progListNames',progListNames);
  }
  if (TSN.length>0) {
      formData.append('TSN', TSN);
      formData.append('treeSpecies', treeSpecies);
  }

  
  if (yearLower!==filters.year_min) {
      formData.append('yearLower', yearLower);

  }
  if (yearUpper!==filters.year_max) {
      formData.append('yearUpper', yearUpper);
  }
  if(!($('.state_sub_checkbox:checkbox:checked').length === $('.state_sub_checkbox').length)){
      formData.append('state', state);
  }
  if (forestHealth.length>0) {
      formData.append('forestHealth',forestHealth);
  }
  if (crown!=="") {
      formData.append('crown',crown);
  }
  if (tree_status.length>0) {
      formData.append('status',tree_status);
  }
  var height_change=false;
  if (heightUpper!==filters.height_max) {
      height_change=true;
      formData.append('heightUpper',heightUpper);
  }
  
  if (heightLower!==filters.height_min) {
      height_change=true;
      formData.append('heightLower',heightLower);
  }
  if (height_change===true || missingHeight===false) {
      formData.append('missingHeight',missingHeight);
  }
  var dbh_change=false;
  if (dbhUpper!==filters.dbh_max) {
      dbh_change=true;
      formData.append('dbhUpper',dbhUpper);
  }
  
  if (dbhLower!==filters.dbh_min) {
      dbh_change=true;
      formData.append('dbhLower',dbhLower);
  }
  if (dbh_change===true || missingDBH===false) {
      formData.append('missingDBH',missingDBH);
  }

   //get options in array for getData variable
  var getData = {};
formData.forEach(function(value, key){
        getData[key] = value;  
});

var getDataJSON = JSON.stringify(getData);

  formData.append('fields',fields);
  formData.append('limit',limit);
  formData.append('offset',offset);
  
updateSearchParamHTML(formData);
  $.ajax({
            url: posturl,
            cache: false,
            data: formData,
            method: 'POST',
            contentType: false,
            processData: false,
            type: 'POST',
            beforeSend: function(){
                $('.progress').show();
                $('.progress-bar').attr('style', 'width: 100%;');

            },
            complete: function(){
                $('.progress').hide();
                $('.progress-bar').attr('style', 'width: 0%;');

            },
            error: function (xhr, status, error) {
                console.log(xhr);
                console.log(status);
                console.log(error);
            },
            success: function (data) {
                var data2 = JSON.parse(data);

                    $('#datasetErrors').removeClass('show');
                    $('#datasetErrors').addClass('hidden');
                    var datasetTable='';
                    
                    $('#getData').val(getDataJSON);

                    if (method==='ajax_getPrograms') {
                        
                        //assemble JSON of programs returned for data download
                        var programArray=[];
//                        console.log(data2);
                        if (data2.data && Object.keys(data2.data).length !== 0) {
                            $.each(data2.data, function (i, d) {
                                programArray.push(d['pkProgramID']);
                            });                       
                        }
                        //console.log(programArray);
                        var projectIDsJSON = JSON.stringify(programArray);
                        $('#projectIDs').val(projectIDsJSON);
                        
                        if (data2.resultCount<limit){
                            $("#program_next_btn").hide();
                        }
                        else {
                            $("#program_next_btn").show();                            
                        }
                        datasetTable = createProgramTable(data2.data);
                        $("#programCount").html('<strong>Your search returned ' data2.resultCount ' program(s) with tree data in our inventory.</strong>');
                        $("#programTable tbody").fadeOut(100, function () {
                            $(this).empty().html(datasetTable).fadeIn(); //Empty content and repopulate
                    });
                }
                if (method==='ajax_getPlots') {                      
                        //console.log(data2);
                        //console.log(programIDs);
                        var programIDs=data2.programIDs;
                        var projectIDsJSON = JSON.stringify(programIDs);
                        $('#projectIDs').val(projectIDsJSON);                        
                        if (data2.resultCount<=limit){
                            $("#plot_next_btn").hide();
                        }
                        else {
                            $("#plot_next_btn").show();                            
                        }
                        datasetTable = createPlotTable(data2.data, data2.fuzzflag);
                        //console.log(data2.fuzzflag);
                        $("#plotCount").html('<strong>Your search returned ' data2.resultCount ' plot observations in our inventory.</strong>');
                        $("#plotTable tbody").fadeOut(100, function () {
                            $(this).empty().html(datasetTable).fadeIn(); //Empty content and repopulate
                    });
                }
                if (method==='ajax_getTrees') {
                        //assemble JSON of programs returned for data download
                        //console.log(data2);
                        var projectIDsJSON = JSON.stringify(data2.programIDs);
                        $('#projectIDs').val(projectIDsJSON);
                       // console.log($('#projectIDs').val());
                        if (data2.resultCount<=limit){
                            $("#tree_next_btn").hide();
                        }
                        else {
                            $("#tree_next_btn").show();                            
                        }                    
                        datasetTable = createTreeTable(data2.data, data2.fuzzflag);
                        $("#treeCount").html('<strong>Your search returned ' data2.resultCount ' tree observations in our inventory.</strong>');
                        $("#treeTable tbody").fadeOut(100, function () {
                            $(this).empty().html(datasetTable).fadeIn(); //Empty content and repopulate
                    });
                }
                $("#download-tab-nav").prop("disabled",false);
                
                //check if we are on the download tab and update downloads if needed
                //console.log ("active tab: " $('#tableTab .active').attr('id'));
                if ($('#tableTab .active').attr('id')=="download-tab-nav"){
                        var programID = $('#projectIDs').val();
                        var posturl = baseURL   "data/ajax_getProgramFiles";
                        var formData = new FormData();   
                        formData.append('programID',programID);
                      $.ajax({
                                url: posturl,
                                cache: false,
                                data: formData,
                                method: 'POST',
                                contentType: false,
                                processData: false,
                                type: 'POST',
                                error: function (xhr, status, error) {
                                    console.log(xhr);
                                    console.log(status);
                                    console.log(error);
                                },
                                success: function (data) {
                                    var data2 = JSON.parse(data);
                                //    var data2=data;
                                //   console.log(data2);
                                   var file_download_div='';
                                   file_download_div = populateFileDownloadDiv(data2);             
                                   $("#fileDownloadDiv").html(file_download_div);
                                   setSelectedFiles();
                                    }
                                });    
                }
                //set hidden field to indicate if any of the programs returned are fuzzed
                var fuzzed=false;
                programArray = $('#projectIDs').val();
                var ajaxurl2 = baseURL   "data/ajax_arefuzzed";
                $.ajax({
                      method: "POST",
                      url: ajaxurl2,
                      data: {data : programArray}
                    })
                      .done(function(data) {
                          var data2 = JSON.parse(data);
                        $('#fuzzPlots').val(data2.fuzzed);
                      });

            }
        });
}

CodePudding user response:

There are 2 ways to do this:

1. Generalise the progress/loading animation for all ajax requests using the below code:

//jQuery 1.9 onwards

// Ref: http://jquery.com/upgrade-guide/1.9/#ajax-events-should-be-attached-to-document

$(document).ajaxStart(function() {
  $('.progress').show();
  $('.progress-bar').attr('style', 'width: 100%;');
});

$(document).ajaxStop(function() {
  $('.progress').hide();
  $('.progress-bar').attr('style', 'width: 0%;');
});

2. Do it this way for your ajax code:

updateSearchParamHTML(formData);
//Show loader before ajax call starts
$('.progress').show();
$('.progress-bar').attr('style', 'width: 100%;');
$.ajax({
    url: posturl,
    cache: false,
    data: formData,
    .
    .
    .
    //Hide loader in complete call
    complete: function(){
        $('.progress').hide();
        $('.progress-bar').attr('style', 'width: 0%;');
    },

I hope any of these will work for you.

CodePudding user response:

By seeing the code and description I understood that you are looking for some progressible tab content where data is coming on tab click and until it did not come progress bar should appear there.

You can add a progress bar in the tab and remove it once data is returned. check the below code might be helpful to you.

var progressBarHtml = '<div id="progressBar"><div id="myBar"></div></div>';
var progressBarspeed = 10;
var intervalId;
var i = 0;

function showProgress(currentTab) {
    if ($("#progressBar").length > 0) {
        $("#progressBar").remove();
        clearInterval(intervalId);
       i = 0;
    }
    $("#"   currentTab).append(progressBarHtml);
    function move() {
        if (i == 0) {
            i = 1;
            var elem = document.getElementById("myBar");
            var width = 1;
            intervalId = setInterval(frame, progressBarspeed);

            function frame() {
                if (width >= 100) {
                    clearInterval(intervalId);
                    i = 0;
                    OnceProgressBarLoaded(currentTab);
                } else {
                    width  ;
                    elem.style.width = width   "%";
                }
            }
        }
    }
    move();
}

function OnceProgressBarLoaded(currentTab) {

    console.log(currentTab   "Tab data Loaded");
    $("#progressBar").remove();
    //call your response here.
    var dataId = currentTab   'Data';
    $("#"   dataId).show();
}

function openCity(evt, tabId) {
    var i, tabcontent, tablinks;
    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i  ) {
        tabcontent[i].style.display = "none";
    }
    tablinks = document.getElementsByClassName("tablinks");
    for (i = 0; i < tablinks.length; i  ) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }
    document.getElementById(tabId).style.display = "block";
    evt.currentTarget.className  = " active";
    $(".tabdata").hide();
    showProgress(tabId);
}

$(document).ready(function() {
    $(".tabdata").hide();
})
 body {font-family: Arial;}
         /* Style the tab */
         .tab {
         overflow: hidden;
         border: 1px solid #ccc;
         background-color: #f1f1f1;
         }
         /* Style the buttons inside the tab */
         .tab button {
         background-color: inherit;
         float: left;
         border: none;
         outline: none;
         cursor: pointer;
         padding: 14px 16px;
         transition: 0.3s;
         font-size: 17px;
         }
         /* Change background color of buttons on hover */
         .tab button:hover {
         background-color: #ddd;
         }
         /* Create an active/current tablink class */
         .tab button.active {
         background-color: #ccc;
         }
         /* Style the tab content */
         .tabcontent {
         display: none;
         padding: 6px 12px;
         border: 1px solid #ccc;
         border-top: none;
         }
         .tabdata {
         background: white;
         }
         #myProgress {
         width: 100%;
         background-color: #ddd;
         }
         #myBar {
         width: 1%;
         height: 30px;
         background-color: #04AA6D;
         }
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
 <h2>Tabs With Loader</h2>
      <p>Click on the buttons inside the tabbed menu:</p>
      <div >
         <button  onclick="openCity(event, 'London')">London</button>
         <button  onclick="openCity(event, 'Paris')">Paris</button>
         <button  onclick="openCity(event, 'Tokyo')">Tokyo</button>
      </div>
      <div id="London" >
         <div id="LondonData" >
            <h3>London</h3>
            <p>London is the capital city of England.</p>
         </div>
      </div>
      <div id="Paris" >
         <div id="ParisData" >
            <h3>Paris</h3>
            <p>Paris is the capital of France.</p>
         </div>
      </div>
      <div id="Tokyo" >
         <div id="TokyoData" >
            <h3>Tokyo</h3>
            <p>Tokyo is the capital of Japan.</p>
         </div>
      </div>

  • Related