'Dynamic XML flow problem with jQuery parsing to HTML page
The problem I have is that this jQuery:
<script type="text/javascript">
$(document).ready(function(){
$.get('CampusList.xml', function(xmltree){
$('#settings').before('<ul id="campuses">');
$(xmltree).find('campus').each(function(){
$('#settings').before('<li class="campus">'+$(this).attr('name')+'<ul id="buildings">');
$(this).find('building').each(function(){
$('#settings').before('<li class="building">'+$(this).attr('name')+'</li>');
});
$('#settings').before('</ul>');
$('#settings').before('</li>');
});
$('#sidebar').before('</ul>');
});
});
</script>
And this is the associated XML:
<campuses name='Campuses'>
<campus name='Clearwater'>
<building name='Clearwater Building 1' img='someimg.png' />
<building name='Clearwater Building 2' img='someimg.png' />
<building name='Clearwater Building 3' />
</campus>
<campus name='Saint Petersburg'>
<building name='St. Pete Building 1' />
<building name='St. Pete Cafe Building' />
<building name='Other Building' />
<building name='Secret Chiller Plant Connection' />
</campus>
<campus name='Epicenter'>
<building name='District Offices' img='epi_do_floor1.png' />
<building name='Services' img='epi_services.png' />
<building name='Tech Building' img='epi_tech.png' />
</campus>
</campuses>
And finally, this is the erroneous output: (I screenshotted the image from chrome's inspector because otherwise it would be all garbled.)
Solution 1:[1]
The problem is that your logic is trying to build the DOM as a string, which is not what happens when you use jQuery.
When you're doing the following:
$('#settings').before('<ul id="campuses">');
jQuery puts it into the DOM properly, closing the tag. That's why you've got an empty <ul id="campuses"></ul>
at the top.
The solution is to build your output as a tree, saving the parent references as you go, and append the nested elements into their respective containers.
Something like this should work:
<script type="text/javascript">
$(document).ready(function(){
$.get('CampusList.xml', function(xmltree){
var $campuses = $('<ul id="campuses">').insertBefore('#settings');
$(xmltree).find('campus').each(function(){
var $campus = $('<li class="campus">'+$(this).attr('name')+'</li>').appendTo($campuses);
var $buildings = $('<ul id="buildings">').appendTo($campus);
$(this).find('building').each(function(){
$buildings.append('<li class="building">'+$(this).attr('name')+'</li>');
});
});
});
});
</script>
Solution 2:[2]
@DarthJDG, while your answer does work, I much prefer the simplicity of the modified version that I made that still utilizes append but just takes advantage of the :last
css pseudoclass for a selector. Here's the code:
<script type="text/javascript">
$(document).ready(function(){
$.get('CampusList.xml', function(xmltree){
$(xmltree).find('campus').each(function(){
$('#campuses').append('<li class="campus">'+$(this).attr('name')+'<ul class="buildings">');
$(this).find('building').each(function(){
$('.buildings:last').append('<li class="building hidden" img="'+$(this).attr('img')+'">'+$(this).attr('name')+'</li>');
});
});
});
});
</script>
I would feel bad marking my answer as the right one though, so I'll give it to you, but I think my approach is probably a bit more efficient.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | DarthJDG |
Solution 2 | Vap0r |