Search code examples
javascriptweb-frontend

Manually placing div start and end tags


I use Madcap Flare to write web help. This comes with useful proxies that auto-generate navigation when built. I need to manipulate one of these proxies. This is important because I have to work within the structure they use, and can't just add my div in the html as usual.

PLEASE NOTE: I cannot directly change the html in this situation. I can only add css or javascript.

So here's the problem. I need to add <div class="eplanation-wrapper"> before <p class="explanation-heading"> and it's closing </div> after the last <p class="explanation-item">.

I've gotten the selectors to work and place the inserts in the correct places, but they are registering as strings, not code.

(The other heading/item class pairings will get the same treatment)

<div class="MCRelationshipsProxy_0">
    <p class="explanation-heading">Related Articles</p>
    <p class="explanation-item"><a href="">link</a></p>
    <p class="explanation-item"><a href="">link</a></p>
    <p class="explanation-item"><a href="">link</a></p>
    <p class="howTo-heading">How To Guides</p>
    <p class="howTo-item"><a href="">link</a></p>
    <p class="reference-headaing">Reference Articles</p>
    <p class="reference-item"><a href="">link</a></p>
</div>

<script>
    const explanationHeading = document.querySelector('p.explanation-heading');
    explanationHeading.before('<div class="explanation-wrapper">');

    const explanationItem = document.querySelectorAll('p.explanation-item');
    const lastExplanationItem = explanationItem[explanationItem.length - 1];
    lastExplanationItem.after('</div>');
</script>

Current broken state: current broken state

GOAL :

<div class="MCRelationshipsProxy_0">
    <div class="explanation-wrapper"><p class="explanation-heading">Related Articles</p>
    <p class="explanation-item"><a href="">link</a></p>
    <p class="explanation-item"><a href="">link</a></p>
    <p class="explanation-item"><a href="">link</a></p></div>
    <p class="howTo-heading">How To Guides</p>
    <p class="howTo-item"><a href="">link</a></p>
    <p class="reference-headaing">Reference Articles</p>
    <p class="reference-item"><a href="">link</a></p>
</div>

I have tried:

before() after()

prepend() append()

insertAdjacentHTML(beforebegin / afterend)

insertAdjacentText(beforebegin / afterend)


Solution

  • Here's one way to do it:

    // Creates a <div></div>
    const explanationWrapper = document.createElement("div");
    
    // Adds a class to the <div class="eplanation-wrapper"></div>
    explanationWrapper.setAttribute("class","eplanation-wrapper");
    
    // Picks all the elements that should be nested inside the div:
    document.querySelectorAll(".explanation-heading, .explanation-item").forEach( el =>{
      // Append each one iteratively to the <div>
      explanationWrapper.appendChild(el);
      // <div class="eplanation-wrapper">{el here}</div>
    })
    
    // Move the <div> with the nested elements directly at the beginning of the parent element:
    document.querySelector(".MCRelationshipsProxy_0")
    .insertAdjacentElement("afterbegin",explanationWrapper);
    

    const explanationWrapper = document.createElement("div");
    
    explanationWrapper.setAttribute("class","eplanation-wrapper");
    
    document.querySelectorAll(".explanation-heading, .explanation-item").forEach( el =>{
      explanationWrapper.appendChild(el);
    })
    
    
    document.querySelector(".MCRelationshipsProxy_0")
    .insertAdjacentElement("afterbegin",explanationWrapper);
    
    console.log(document.querySelector(".MCRelationshipsProxy_0").outerHTML);
    <div class="MCRelationshipsProxy_0">
        <p class="explanation-heading">Related Articles</p>
        <p class="explanation-item"><a href="">link</a></p>
        <p class="explanation-item"><a href="">link</a></p>
        <p class="explanation-item"><a href="">link</a></p>
        <p class="howTo-heading">How To Guides</p>
        <p class="howTo-item"><a href="">link</a></p>
        <p class="reference-headaing">Reference Articles</p>
        <p class="reference-item"><a href="">link</a></p>
    </div>