##  [Adding Aside Content to CKEditor 5 in Drupal: A JavaScript Solution Part 2](/adding-aside-content-to-ckeditor-5-in-drupal-a-javascript-solution-part-2) 

This is part 2 and the last part of adding aside elements to content created using CKEditor 5. Since at the time of writing, there wasn't a widget to insert aside content I decided to go the quick hacking route and use JavaScript to convert elements that have been styled in CKEditor. If you want more information on the set up I suggest you read[ part 1 where we also create the aside element and add the blockquote element as a child](/adding-aside-content-to-ckeditor-5-in-drupal-a-javascript-solution "how to use insertbefore and appendchild instance methods in Javascript").

In this part, we will be removing the unneeded wrapper element used in CKEditor. In this case, we used a blockquote and the resulting HTML markup from part 1 is shown below.

```html
<aside>
    <blockquote class="hint">
        <h2>
            Heading of a hint aside
        </h2>
        <p>
            Something semi-related to the main content, an aside.
        </p>
    </blockquote>
</aside>
```

**What we use**  
`querySelectorAll()` instance method  
`while` statement  
`forEach()` array method  
`DocumentFragment()` constructor  
*Plus other Javascript methods and properties.*

## Remove the `blockquote` element but not its children using a JavaScipt `DocumentFragment`

To remove an element but not the children of an element we can use the `createDocumentFragment()` method. We can use fragments to save segments of the document structure. Fragments are not part of the main DOM tree (active document tree structure.)

```javascript
const hint = document.querySelector('blockquote.hint');
const asideNode = document.createElement("aside");
hint.parentNode.insertBefore(asideNode, hint);
asideNode.appendChild(hint);
```

Continuing on from what we already have from Part 1 as shown above, follow these steps:

1. First, create a new constant and assign a new fragment to it. We can use the `DocumentFragment` constructor to do this.

```javascript
const fragment = new DocumentFragment();
```

2. Then we can use a while statement to loop through all the elements inside out hint element and add them to the fragment.

```javascript
while (hint.firstChild) {
  fragment.appendChild(hint.firstChild);
}
```

3. Next, we add the fragment to the aside element using the appendChild method

```javascript
asideNode.appendChild(fragment);
```

4. Then remove the hint element.

```javascript
hint.remove();
```

5. Finally, you'll need to add a class to the aside element so you can style it.

```javascript
asideNode.className = 'hints';
```

Then in your CSS, you'll need to add a rule to style the `aside` element. The example CSS is from the styles we added to the `blockquote` element when [setting up the styles to use in CKEditor 5](/how-to-add-custom-styles-to-elements-in-the-drupal-wysiwyg "how to add custom styles in Drupal CKEditor 5").

```css
aside.hints {
  padding: 1rem;
  color: #107A0E;
  background-color: #F5FAF2;
  border: 1px solid #B6DEA5;
  border-left: 5px solid #B6DEA5;
  font-style: normal;
}
```

That's it, we have now removed the `blockquote` element from the DOM tree but not its children. Your code should look like this below.

```html
<aside>
    <h2>
        Heading of a hint aside
    </h2>
    <p>
        Something semi-related to the main content, an aside.
    </p>
</aside>
```

The final thing you will most probably want to do is apply the same process to all the elements that have the same class applied. To do this we use querySelectorAll and a forEach loop.

## Using querySelectorAll &amp; forEach to target and convert all elements of the same class

With the code from the last section, we will make a few changes to convert all elements with the class hint.   
The first change we will make is the `querySelector` method. Change this to `querySelectorAll`.

```diff
-const hint = document.querySelector('blockquote.hint');
+const hint = document.querySelectorAll('blockquote.hint','p.hint'); 
```

By using querySelectorAll we get an array of elements which we have stored in the constant hint. You will notice that I have added the paragraph hints here too. This is more for demonstration that you can add multiple selectors separated by a comma. Please read the following note.

We then need to loop through each element and apply the same changes. To do this we use the forEach loop. Below is the code showing the differences from our single-element conversion above.

```javascript
hint.forEach((b) => {
  const asideNode = document.createElement("aside");
  b.parentNode.insertBefore(asideNode, b);
  asideNode.appendChild(b);
  
  const fragment = new DocumentFragment();
  while (b.firstChild) {
    fragment.appendChild(b.firstChild);
  }
  asideNode.appendChild(fragment);
  b.remove();
  asideNode.className = 'hints';
}
```

1. The first thing we have done is wrap our code block in a `forEach` loop and passed in each value of our hint array as an argument. In this case, our argument is b.
2. Then, we switched out all occurrences of the reference to the querySelector value, which is hint, for the argument which is passed in.

That's it. Now all our elements on the page with the class hint are wrapped in an aside element with the original element removed.

## Thoughts about `aside` elements and document structure

You will notice that now the paragraph tag that had the hint class is removed. Even though I can't find anywhere that explicitly states this is wrong, in the specification it does say "The aside element represents a section of a page that consists of content...". In reading this I do get the feeling that it is best to have structure inside the `aside` so in the case we have just worked on I would not include the `p.hint` in the `querySelectorAll` method.

Also, taking the above case into consideration sometimes you may want to have a blockquote inside the aside. If that is the case then you would need to set up these types of blockquotes with a different class so they weren't included.

That's it for this small snippet. We have learnt how you can change the parent element type using JavaScript. In this case, we replace the blockquote with an aside to make it semantically correct but you could use this snippet to change any parent element.

For me, this was a good refresher and I am using this on production until I get time to build an aside widget for CKEditor 5. It's a great quick solution that allowed me to use something I am comfortable working with, without the need to learn something new.

If you enjoyed this and would like to learn more about front-end development and design be sure to sign up for the newsletter below.

Thanks for reading!



Tags

[JavaScript](/javascript)

 

 

## Add new comment

  Your name  

 Email  The content of this field is kept private and will not be shown publicly. 

 

 Homepage  

 Comment 

 

[About text formats](/filter/tips)

#### Plain text

- Allowed HTML tags: &lt;a href hreflang&gt; &lt;em&gt; &lt;strong&gt; &lt;cite&gt; &lt;blockquote cite&gt; &lt;code&gt;
- Lines and paragraphs break automatically.
- Web page addresses and email addresses turn into links automatically.
 
 





Please leave questions and constructive comments, I welcome them.

 

 

 

   CAPTCHA  

 

This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.

 

 Leave this field blank