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);
});
}
});
}
The HTML
<div class="table-responsive">
<table id="plotTable" class="table table-striped table-centered" style="width:100%">
<thead>
<tr>
<th>Plot ID</th>
<th>Latitude</th>
<th>Longitude</th>
<th>Sample Year</th>
<th>Original Data</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-center" colspan="5">
<div class="progress">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%">
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
3
Answers
What was happening is that in the success code of the ajax call I was replacing the tbody of each table. For example, in the plotTable:
But the progress bar was in the tbody of the table. So then when I wanted to set the progress bar to be visible, it was no longer in the table.
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
2. Do it this way for your ajax code:
I hope any of these will work for you.
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.