I have some code with dynamically expanding menus. From my Python Django view, I am passing a JSON array to set the status of checkboxes to checked. There is a hidden div which loads the check boxes, but I can only change the status when there is an alert used.
The code is below and HTML of one of the divs looks as below:
for (var key in interestsselected) {
genres = interestsselected[key];
//Tick interest
$("#id_interest_" + key).prop("checked", true);
getSubinterests(key); //Gets the sub menu
$("#interest-" + key).show(); //Hiding or showing makes no difference
//alert($("#interest-"+key)); //Will work if this line is uncommented
for (i = 0; i < genres.length; i++) {
$("#" + key + "-" + genres[i]).prop("checked", true);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="offset-sm-1 subinterests" id="interest-5" style="">
<label class="interest"><input type="checkbox" class="subinterest 5" id="5-FA" name="genre[]" value="5-FA">Factual</label><br>
<label class="interest"><input type="checkbox" class="subinterest 5" id="5-SF" name="genre[]" value="5-SF">Science Fiction</label><br>
<label class="interest"><input type="checkbox" class="subinterest 5" id="5-TH" name="genre[]" value="5-TH">Thriller</label><br>
<label class="interest"><input type="checkbox" class="subinterest 5" id="5-SU" name="genre[]" value="5-SU">Superhero</label><br>
<label class="interest"><input type="checkbox" class="subinterest 5" id="5-F" name="genre[]" value="5-F">Fantasy</label><br>
<label class="interest"><input type="checkbox" class="subinterest 5" id="5-H" name="genre[]" value="5-H">Horror</label><br>
</div>
The code above is already encased within $(document).ready. I have tried encasing the inner for loop with another $(document).ready, but that doesn't work. I have tried adding the inner for loop as part of the function getSubinterests, passing the genres array to it, but that is the same story.
I have tried encasing the for loop in "$("#interest-"+key).ready", but still the same, I have tried "$("#interest-"+key).load", but get an error so tried "$("#interest-"+key).ready("load",function", same problem. I have tried all of these again with "$("#"+key+"-"+genres[i])", but still the same issue.
The code below is the getSubinterests function:
function getSubinterests(interestid) {
$.ajax({
type: "POST",
url: "/user/getsubinterests/",
data: { csrfmiddlewaretoken:'{{ csrf_token }}',
interestid: interestid },
success: function(data) {
//console.log(data);
var interesttext = "";
for (var key in data) {
//Add returned data under the interest
interesttext = interesttext + "<label class='interest'><input type='checkbox' class='subinterest "+interestid+"' id='"+interestid+"-"+key+"' name='genre[]' value='"+interestid+"-"+key+"' >"+data[key]+"</label><br>";
//alert(data[key]);
}
$("#interest-"+interestid).html(interesttext);
//Capture clicks on the checkboxes that have been added
$(".subinterest").click(function() {
id = $(this).attr('id').split("-")[0];
if(!($("#id_interest_"+id).prop("checked"))) {
$("#id_interest_"+id).prop("checked",true);
}
});
}
});
}
SOLUTION:
function getSubinterests(interestid) {
$.ajax({
type: "POST",
url: "/user/getsubinterests/",
data: { csrfmiddlewaretoken:'{{ csrf_token }}',
interestid: interestid },
success: function(data) {
//console.log(data);
var interesttext = "";
var genres = [];
if(interestsselected[interestid]) {
genres = interestsselected[interestid];
}
for (var key in data) {
//Add returned data under the interest
if (genres.includes(key)) {
//Check the box
interesttext = interesttext + "<label class='interest'><input type='checkbox' class='subinterest "+interestid+"' id='"+interestid+"-"+key+"' name='genre[]' value='"+interestid+"-"+key+"' checked>"+data[key]+"</label><br>";
} else {
interesttext = interesttext + "<label class='interest'><input type='checkbox' class='subinterest "+
interestid+"' id='"+interestid+"-"+key+"' name='genre[]' value='"+interestid+"-"+key+"' >"+data[key]+"</label><br>";
}
}
$("#interest-"+interestid).html(interesttext);
}
I understood the async problem and took a different approach where the HTML is rendered from within the success of the AJAX call by reading the global variable which contains the JSON.