DOM manipulation - using Array method on HTML tags
Tags: html, beginners, challenge, javascript
Published: 2022-12-08 18:13:34

I was familiar with working with objects in JavaScript and how to manipulate them. But until today I didn't know that you could do the same with DOM nodes by manipulate the DOM and iterate through nested DOM elements.

## Task
Given a list of Pokemon, each Pokemon will be encapsulated in a `<div>` with a class of `pokemon`. Inside this `<div>` are three DOM nodes: An `<h3>` indicating the name of Pokemon. A `<p>` containing a child `<span>` with the class `catched` that indicates whether the Pokemon is catched or not.

The goal is to find all Pokemon where `catched` is `true` and append them as children of the section `Catched Pokemon` with the id `catched-pokemon`.

### HTML

```HTML
<h1>Pokemon</h1>
<h2 style="color:green">Wanted Pokemon</h2>
<section class='all-pokemon'>
  <div class='pokemon'>
    <h3>Bulbasaur</h3>
    <p>Catched: <span class='catched'>true</p>
  </div>
  <div class='pokemon'>
    <h3>Charmander</h3>
    <p>Catched: <span class='catched'>false</p>
  </div>
  <div class='pokemon'>
    <h3>Squirtle</h3>
    <p>Catched: <span class='catched'>true</p>
  </div>
  <div class='pokemon'>
    <h3>Pikachu</h3>
    <p>Catched: <span class='catched'>false</p>
  </div>
  <div class='pokemon'>
    <h3>Vulpix</h3>
    <p>Catched: <span class='catched'>false</p>
  </div>
  <div class='pokemon'>
    <h3>Psyduck</h3>
    <p>Catched: <span class='catched'>true</p>
  </div>
  <div class='pokemon'>
    <h3>Machop</h3>
    <p>Catched: <span class='catched'>true</p>
  </div>
</section>

<h2 style="color:blue">Catched Pokemon</h2>
<section id='catched-pokemon'></section>
```

## Possible Solution

Let's add some JavaScript to manipulate the DOM nodes and put all Pokemon where `catched` is `true` under the `Catched Pokemon` section.

```javascript
const pokemon = Array.from(document.getElementsByClassName("catched"));

const catched = pokemon.filter((pokemon) => pokemon.innerHTML === "true");

const onlyCatched = document.getElementById("catched-pokemon");

catched.forEach((catched) => {
  let parent = catched.parentElement.parentElement;
  onlyCatched.appendChild(parent);
});
```

What's happening here?

We are using the [Array.from() method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from?retiredLocale=de), which is a static method that creates a new, shallow-copied array instance from an iterable or array-like object. We store the `<span>` nodes with the class `catched` in `const pokemon`.

We then use the [filter function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) to go over the new array and return only the Pokemon which `innerHTML` value is `true` and store it in `const catched`.

We now need to get the node where we want to display our new array of all catched Pokemon, and store it in `const onlyCatched`.

Lastly, we use a [forEach() function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) to apply changes to all the pokemon stored in the array called `catched`. 

At the current stage we only had access to the `<span>` nodes, but want to show the whole Pokemon node. Therefore, we are using [parentElement](https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement) property twice to first get the `<p>` with which the `<span>` is surrounded and then the `<div>`, which stores all information needed.


[Check out the source code](https://codepen.io/YuriDevAT/pen/RwJbyWW?editors=1111). Using console.log will show you what is stored after each step for better understanding. 

I am more than happy if you have other solutions to share so everyone can learn from it.

---
![Thank you](https://docs.google.com/uc?export=download&id=166Ecq6uBl61U14OUlkHOHIBv2ArKoumJ)

_Thanks for your reading and time. I really appreciate it!_