Using javascript to create the content of the body of a modal i notice that the result is not always the same. Sometimes the modal body is empty some times is as expected. The function is this:
function newServiceModal() {
$("#newServicesModal-bd").html("");
$("#newServiceModalHiddenId").val("");
$("#newServiceModal-title").html("New Service - body not created yet ");
var modalbody = "";
var div = document.createElement('div');
//var provideroptions = {
// providerid:providerid
//}
$.ajax({
type: 'post',
url: baseSiteURL + 'home/ReturnProviders', //supposed to return all available providers
//data: options
}).done(function (data) {
$("#newServiceModal-title").html("New Service - body was created");
modalbody = modalbody.concat(" <div class='col-md-4'> <p>Provider</p><select id='newproviderSelect' class='form-control'>");
for (i = 0; i < data.length; i++) {
if (i==0)
modalbody = modalbody.concat(" <option value=" + data[i].id + " selected>Type: " + data[i].providerType + "</option>");
else
modalbody = modalbody.concat(" <option value=" + data[i].id + ">Type: " + data[i].providerType + "</option>");
}
modalbody = modalbody.concat('</select></div>');
div.innerHTML = modalbody;
document.getElementById('editServicesModal-bd').appendChild(div);
$("#newServiceModal-title").html("New Service - body was created");
})
//var customeroptions = {
// customerid: customerid
//}
$.ajax({
type: 'post',
url: baseSiteURL + 'home/ReturnCustomers', //supposed to return all available customers
//data: options
}).done(function (data) {
modalbody = modalbody.concat(" <div class='col-md-4'> <p>Customer</p><select id='newcustomerSelect' class='form-control'>");
for (i = 0; i < data.length; i++) {
if (i==0)
modalbody = modalbody.concat(" <option value=" + data[i].id + " selected>" + data[i].company + "</option>");
else
modalbody = modalbody.concat(" <option value=" + data[i].id + ">" + data[i].company + "</option>");
}
modalbody = modalbody.concat('</select></div>');
div.innerHTML = modalbody;
document.getElementById('editServicesModal-bd').appendChild(div);
})
//var applicationroptions = {
// applicationid: applicationid
//}
$.ajax({
type: 'post',
url: baseSiteURL + 'home/ReturnApplications', //supposed to return all available applications
//data: options
}).done(function (data) {
modalbody = modalbody.concat(" <div class='col-md-4'> <p>Application</p><select id='newapplicationSelect' class='form-control'>");
for (i = 0; i < data.length; i++) {
if (i==0)
modalbody = modalbody.concat(" <option value=" + data[i].id + " selected>" + data[i].name + "</option>");
else
modalbody = modalbody.concat(" <option value=" + data[i].id + ">" + data[i].name + "</option>");
}
modalbody = modalbody.concat('</select></div>');
div.innerHTML = modalbody;
document.getElementById('newServicesModal-bd').appendChild(div);
})
$("#newServiceModal").modal('show');
}
the modal html is this:
<div id="newServiceModal" class="modal fade local-modal" role="dialog" aria-hidden="true" position="fixed">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<section id="newService">
@using (Html.BeginForm("Services", "Home", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="newServiceModal-title">original title</h4>
</div>
<div id="newServiceModalHiddenId"></div>
<div class="modal-body row" id="newServicesModal-bd" style='margin-right:20px; margin-left:20px;'>
@* bootstrap.min.css applies here this rule : .row{margin-right:-15px;margin-left:-15px} *@
@* services.js puts content here *@
</div>
<div class="modal-footer">
<div class="col-md-6 pull-left">
<button id="savebtn" type="button" class="btn btn-primary ladda-button" data-style="expand-right" data-size="l" onclick="saveNewService()"><span class="ladda-label">Save</span></button>
<button type="button" class="btn btn-warning" data-dismiss="modal" aria-hidden="true">Close</button>
</div>
@*<div class="col-md-6">
<button type="button" class="btn btn-danger" onclick="deleteUser()">Delete</button>
</div>*@
</div>
}
</section>
</div>
</div>
The first line of the function
$("#newServicesModal-bd").html("");
is emptying the modal body (to not have concatenated the previous content with what is about to be created). I imagine my problem is related with this, because 9 of 10 times the modal is created as expected but some times its body is empty, which makes me suspect that either the body content is not created at all or the
$("#newServicesModal-bd").html("");
is executed after the body content is created. To verify that the content does get created i have this
$("#newServiceModal-title").html("New Service - body not created yet ");
right after i empty the body of the modal and i put this
$("#newServiceModal-title").html("New Service - body was created");
when i get some content created.
I would see the title always to be "New Service - body was created" so i think that its safe to assume that the body does get created. I read about hoilsting and scope and i dont think think that they have to do with this matter can't find but in any case i can find any reason for this inconsistent behaviour. If any one could point out why this happens i would appreciate it. Thank you for reading this.
Solution (?)
I investigated a little more and i want to make some more comments, maybe i will clarify the problem better. The function newServiceModal() is making 3 calls to different other functions. ReturnProviders, ReturnCustomers and ReturnApplications(which are in my HomeController class) and they are calling the functions that are actually retrieving the data from the database. I found that the problem occurs only when they (ReturnProviders, ReturnCustomers and ReturnApplications) are not called with this order. The reason that they are not called with the same order as they are written in the function was shown to me by a seasoned programmer after i explained him the problem and he googled, totally he needed 5 minutes. I just added
async: false
in my ajax requests and now the results are coming in the order that are expected. It was pointed out to me that my approach is not correct and i should be making one ajax call for all the data i need instead of 3. So i will post the correct solution as soon as i do it. Thank you all for your time and help.
I managed to solve the problem by making one ajax call, i think that the solution is irrelevant with my question, if anyone is interested email me to give more information. As far as my original question is concerned the answer is that the ajax requests are being executed as they are written in the function but sometimes the results are not coming back in the same order unless this is added to the ajax call
async: false
Solution was found in this post How do I make jQuery wait for an Ajax call to finish before it returns?