skip to Main Content

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)

3

Answers


  1. Here’s one way to do it:

    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);
    
    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>
    Login or Signup to reply.
  2. .before() and .after() will insert the parameters as strings unless they are DOM nodes.

    You essentially need to remove the items from the DOM, wrap them in your new div and insert the bundle back into the DOM.

    const explanationHeading = document.querySelector('p.explanation-heading');
    const explanationItem = document.querySelectorAll('p.explanation-item');
    const lastExplanationItem = explanationItem[explanationItem.length - 1];
    
    let wrapper = document.createElement( "div" )
    wrapper.classList.add( "explanation-wrapper" )
    
    for( let item of explanationItem ) {
      // This effectively moves the item
      wrapper.appendChild( item )
    }
    
    explanationHeading.insertAdjacentElement( "beforebegin", wrapper )
    wrapper.insertAdjacentElement( "afterbegin", explanationHeading )
    .explanation-wrapper {
      background-color: #c0ffee;
      border: 2px solid #cab;
      box-shadow: 2px 2px 4px black;
    }
    .explanation-wrapper div {
      margin-left: 1rem;
      text-decoration: none;
    }
    
    .explanation-heading {
      border-bottom: 1px solid red;
      margin: 1rem 1rem;
    }
    
    .howTo-heading {
      border-bottom: 1px solid blue;
      margin: 1rem 1rem;
    }
    
    .reference-headaing {
      border-bottom: 1px solid green;
      margin: 1rem 1rem;
    }
    <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>
    Login or Signup to reply.
  3. Just another approach for added examples.

    function wrapIt() {
      let
         p = document.querySelector('.MCRelationshipsProxy_0'),
         w = document.createElement("div")
      ;
      w.classList.add('explanation-wrapper');
      w.append(...document.querySelectorAll(
         '.MCRelationshipsProxy_0 > p.explanation-heading, .MCRelationshipsProxy_0 > p.explanation-item'));
      p.prepend(w);
    }
     
    document.querySelector('button').addEventListener(
       'mousedown',
       wrapIt,
       false
    );
    .MCRelationshipsProxy_0 {
      border: 2px solid blue;
      padding: 10px;
    }
    
    
    .explanation-wrapper {
      border: 1px solid black;
      background-color: rgb(240,240,240);
    }
    <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>
    
    
    <button>Wrap It(for illustration only)</button>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search