How to properly navigate a li tag to build a OBJECT in a HTA

52 Views Asked by At

I am trying to build a tool to dynamically build and edit a JSON file. I created a HTA that will dynamically create elements for each data type and build it out in the UI using li and ul. The basic format of these are

<li type='list'> 
   <span>Name</span>
   <div> bunch of html that has hidden edit pop up windows and other controls </div>
   <li><ul> sub entries </ul></li>
</li>

There is one for each type of entry. It pulls these templates out of a library of template files. The problem I am having is walking through the finished UI to build the JSON file. Even though the <li><ul></ul></li> is inside of the the parent li it seems when I try to walk through the DOM to fetch everything it treats all the li as if they are at the same level. Kind of hard to shave it down to a bite size example to put on here because the whole thing pulls on other files to work. I tried doing a mix of jquery and queryselects but all the ways I tried it grabs the sub li along with the first parent li. So clearly I don't understand things as well as I thought I did.

Here is a image of what the placeholder UI looks like.

enter image description here

Also I have to use things as they are I cant use any other software or language for this particular project. I tried to build out the Object as the Entries were added but even though I got it kind of working it was hard to follow and I know for a fact that in a month or so when I have to update something I wont be able to understand what I was doing. So the question is am I going about the building of the list elements all wrong? Or am I going about getting the info from the finished UI all wrong? Should I be using something other than li and ul?

Here is a mini example I was able to make.

<html>
    <head>
        <meta charset="UTF-8" http-equiv="x-ua-compatible" content="ie=edge">
        <title>JSON Builder</title>         
    </head>
    
    
    
    <body>
        <button style="width: 100%" onclick="getChildren()">Get</button>
        <div style="height: 100%; width: 100%;"  >
            <ul id="options" style="height: 100%; border: 2px ridge; border-radius: 10px;">
            
                <li id="entry_X" type="string" >
                    <div style="width: 15em;" >
                        <span id="entry_name_X"  >Root 0</span>     
                    </div>
                    
                    <li>
                        <ul>
                        
                            <li id="entry_1" type="string" >
                                <div style="width: 15em;" >
                                    <span id="entry_name_1"  >1</span>      
                                </div>
                                
                                <!-- This should be nested inside the li by my understanding but isnt so i was hiding them to get the look i wanted. -->                                
                                <li style='display: none;'>
                                    <ul>
                                    </ul>
                                </li>
                                
                            </li>
                            
                            <li id="entry_2" type="string" >
                                <div style="width: 15em;" >
                                    <span id="entry_name_2"  >2</span>      
                                </div>
                                
                                <li style='display: none;'>
                                    <ul>
                                    </ul>
                                </li>
                                
                            </li>
                                    
                        
                        
                        </ul>
                    </li>
                    
                </li>
                
                <li id="entry_6" type="string" >
                    <div style="width: 15em;" >
                        <span id="entry_name_X"  >Root 1</span>     
                    </div>
                    
                    <li>
                        <ul>
                        
                            <li id="entry_7" type="string" >
                                <div style="width: 15em;" >
                                    <span id="entry_name_7"  >7</span>      
                                </div>
                                
                                <li style='display: none;'>
                                    <ul>
                                    </ul>
                                </li>
                                
                            </li>
                            
                            <li id="entry_8" type="string" >
                                <div style="width: 15em;" >
                                    <span id="entry_name_8"  >8</span>      
                                </div>
                                
                                <li style='display: none;'>
                                    <ul>
                                    </ul>
                                </li>
                                
                            </li>
                                    
                        
                        
                        </ul>
                    </li>
                    
                </li>
                
            </ul>
        </div>
    
    
    
        
    
        
    </body>
    
    <script>
        function getChildren() {
                // This returns a length of 6 items
                var l1 = document.querySelectorAll( 'ul>li' );
                alert( "[ QALL ul>li length ] " + l1.length );
                
                /* 
                    This returns a length of 2 items. 
                    the first item is the div in the first li and the 2nd is 
                    the li inside the first li. 
                    
                    I expected this to return just the 1 li as there is only 1 li in 
                    the options ul but that is not how its working. 
                
                */
                var l1 = document.querySelector( '#options' ).children;
                alert( "[ QSEL options.children length ] " +  l1.length );                              
                //alert( l1[0].innerHTML );
                //alert( l1[1].innerHTML );
                
                
                var l1 = document.querySelectorAll( '#options ul>li' );
                alert( "[ QSEL2 options.children length ] " +  l1.length );

            }
            
    </script>
    
    <script> 
            resizeTo( 690,390 );            
            moveTo(screen.width/2-210,screen.height/2-250);
        </script>   
    
    
    
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
</html>
1

There are 1 best solutions below

0
tokageKitayama On
<html>
    <head>
        <meta charset="UTF-8" http-equiv="x-ua-compatible" content="ie=edge">
        <title>JSON Builder</title>         
    </head>
    
    <body>
        <button style="width: 100%" onclick="getChildren0()">Get 1</button>
        <button style="width: 100%" onclick="getChildren1()">Get 7</button>
        <div style="height: 100%; width: 100%;"  >
            <ul id="options" style="height: 100%; border: 2px ridge; border-radius: 10px;">
            
                <li id="entry_X" type="string" >
                    <div style="width: 15em;" >
                        <span id="entry_name_X"  >Root 0</span>     
                    </div>                                  
                        <ul>                        
                            <li id="entry_1" type="string" >
                                <div style="width: 15em;" >
                                    <span id="entry_name_1"  >1</span>      
                                </div>
                                <ul></ul>
                            </li>
                            
                            <li id="entry_2" type="string" >
                                <div style="width: 15em;" >
                                    <span id="entry_name_2"  >2</span>      
                                </div>
                                <ul></ul>   
                            </li>
                        </ul>
                </li>
                
                <li id="entry_6" type="string" >
                    <div style="width: 15em;" >
                        <span id="entry_name_X"  >Root 1</span>     
                    </div>                                  
                        <ul>                        
                            <li id="entry_7" type="string" >
                                <div style="width: 15em;" >
                                    <span id="entry_name_7"  >7</span>      
                                </div>
                                    <ul></ul>
                            </li>
                            
                            <li id="entry_8" type="string" >
                                <div style="width: 15em;" >
                                    <span id="entry_name_8"  >8</span>      
                                </div>
                                    <ul></ul>
                            </li>
                        </ul>                                       
                </li>               
            </ul>
        </div>  
    </body>
    
    <script>
        function getChildren0() {
                var l1 = document.querySelector( '#options' ).children;             
                var output = "[ id ] = " + l1[0].querySelector('ul').children[0].id + " [ value ] = " + l1[0].querySelector('ul').children[0].querySelector('span').innerHTML               
                alert( output );            
            }
        function getChildren1() {
                var l1 = document.querySelector( '#options' ).children;
                var output = "[ id ] = " + l1[1].querySelector('ul').children[0].id + " [ value ] = " + l1[1].querySelector('ul').children[0].querySelector('span').innerHTML               
                alert( output );            
            }           
    </script>
    
    <script> 
            resizeTo( 690,390 );            
            moveTo(screen.width/2-210,screen.height/2-250);
    </script>
</html>

The fix was posted by the comments above. Here is a fixed version of the example. Simple solution but for some reason I just couldn't see it.