javascriptvue.jsrecursiontreeviewrecursive-query

How to create tree structure from html element?


this is my element in my vue2 application:

<div class="child-elements-container draggable-container">
    <div>
        <div entity-type="entitytype1" type="elementType" id="2" class="single-element"></div>
        <div class="child-elements-container draggable-container">
            <div>
                <div entity-type="entitytype2" type="elementType" id="59" class="single-element"></div>
            </div>
        </div>
    </div>
    <div>
        <div entity-type="measures" type="elementType" id="3" class="single-element"></div>
        <div class="child-elements-container draggable-container">
            <div>
                <div entity-type="entitytype3" type="elementType" id="13" class="single-element"></div>
                <div class="child-elements-container draggable-container"></div>
            </div>
            <div>
                <div entity-type="entitytype2" type="elementType" id="14" class="single-element"></div>
                <div class="child-elements-container draggable-container"></div>
            </div>
        </div>
    </div>
    <div>
        <div entity-type="entitytype3" type="elementType" id="11" class="single-element">
        </div>
        <div class="child-elements-container draggable-container">
            <div>
                <div entity-type="entitytype3" type="elementType" id="12" class="single-element">
                </div>
                <div class="child-elements-container draggable-container"></div>
            </div>
        </div>
    </div>
</div>

I am trying to get a tree structure with the id's of single-element and I am using this function to get this hierarchy view:

   buildDraggedHierarchy(el) {
            if (!el) {
                return [];
            }

            const children = [...el.querySelectorAll(":scope>div")];
            const output = children.map((child) => ({
                id: child.querySelector(".single-element") ? child.querySelector(".plan-element").id : null, 
                type: child.getAttribute("type"), 
                children: this.buildDraggedHierarchy(child.querySelector(".draggable-container")), 
            }));

            return output;
        },

but output comes like this:

[
    {
        "id": "2",
        "type": null,
        "children": [
            {
                "id": "59",
                "type": null,
                "children": []
            }
        ]
    },
    {
        "id": "3",
        "type": null,
        "children": [
            {
                "id": "13",
                "type": null,
                "children": []
            },
            {
                "id": "14",
                "type": null,
                "children": []
            }
        ]
    },
    {
        "id": "11",
        "type": null,
        "children": [
            {
                "type": null,
                "children": []
            }
        ]
    }
]

so the last element's children doesnt come correct. I would expect the children comes with and id 12 instead id doesnt shown at all. how can I fix this issue?


Solution

  • A few issues:

    Here's the fix:

    const element = document.querySelector(".child-elements-container");
    const elementHierarchy = this.buildDraggedHierarchy(element);
    console.log(elementHierarchy);
    
    function buildDraggedHierarchy(el) {
        if (!el) {
            return [];
        }
        let children = [...el.querySelectorAll(":scope>div")];
        return children.map((child) => {
            const elem = child.querySelector(".single-element");
            return {
                id: elem.id,
                type: elem.getAttribute("type"),
                children: this.buildDraggedHierarchy(child.querySelector(".draggable-container")),
            };
        });
    }
    <div class="child-elements-container draggable-container">
        <div>
            <div entity-type="entitytype1" type="elementType" id="2" class="single-element"></div>
            <div class="child-elements-container draggable-container">
                <div>
                    <div entity-type="entitytype2" type="elementType" id="59" class="single-element"></div>
                </div>
            </div>
        </div>
        <div>
            <div entity-type="measures" type="elementType" id="3" class="single-element"></div>
            <div class="child-elements-container draggable-container">
                <div>
                    <div entity-type="entitytype3" type="elementType" id="13" class="single-element"></div>
                    <div class="child-elements-container draggable-container"></div>
                </div>
                <div>
                    <div entity-type="entitytype2" type="elementType" id="14" class="single-element"></div>
                    <div class="child-elements-container draggable-container"></div>
                </div>
            </div>
        </div>
        <div>
            <div entity-type="entitytype3" type="elementType" id="11" class="single-element">
            </div>
            <div class="child-elements-container draggable-container">
                <div>
                    <div entity-type="entitytype3" type="elementType" id="12" class="single-element">
                    </div>
                    <div class="child-elements-container draggable-container"></div>
                </div>
            </div>
        </div>
    </div>