How to master the DOM to build interactive web apps
Tags: webdev, javascript, beginners, tutorial
Published: 2023-05-15 18:47:00

Frontend JavaScript uses the DOM, hence if you want to be good at JavaScript you will need to master the DOM.

In this article, you will learn how to use the Document Object Model (DOM) to connect and manipulate the elements of a web page to make it dynamic.

At the end of this article, you will learn:

- What the DOM is
- Understand the DOM Tree 
- How to select, create, add, and remove elements from a web page
- Styling a web page using JavaScript 
- Traversing the DOM
- Event handling in the DOM etc

You will use this knowledge to create this basic web app, called "Hey Buddy", that enables you to create and access the contact details of your favorite buddies.

![DOM Manipulation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n4ghg10xjnrl06b44vrw.png)

## Prerequisite

Before getting started, you will need to be familiar with

- Basic HTML
- Basic CSS
- Basic JavaScript

## Introduction

Websites consist of static `HTML` and or `XML` documents. Being static, you need an approach to make them lively and functional.

You may want to change the background color of a specified content on the web page when the user hovers over it.

You may also want to validate a form whenever a user enters a piece of information, warning the user of any incorrect input.

You may even want to expand an image when the user hovers it.

**These interactivities are made possible when you have access to the elements on the web page.**

**How do you access these elements?** Whenever a `HTML` document is loaded in a web browser, the browser models the HTML document into a structure.

With this structure, you can use a programming language like JavaScript to access and modify the various elements in the HTML document.

Whenever any section of the `HTML` document is modified with JavaScript, the web page reloads to reflect the changes.

This approach enables developers to add interactivity and control the elements in any `HTML` file making websites dynamic and functional.

In the next section, you will learn about the Document Object Model.

## What is the DOM?

Whenever a web page is displayed in a browser window, the browser depicts everything on the page **(heading, paragraph, images, links, text, etc)** as objects. These objects represents the structure and content of every element on the website, and is generally referred to as the Document Object Model (DOM).

**The Document Object Model (DOM) is a tree-like representation of the content of the web page.**

It enables you to use a programming language such as JavaScript to change the **content, style, and structure** of web pages to make them dynamic and functional.

## The DOM and JavaScript

Whenever a web page is loaded, the browser creates a Document Object Model (DOM) of the page. This means, **every element on the web page is represented as an object, and these objects act as a link between JavaScript and the web page.**

Because every element on the web page has been represented as an `object`, you can use JavaScript to interact with the elements on a web page.

The elements that will be depicted as `object` could be any of the below:

- Content: these include text, video, and images on the web page.

- Structural elements: These include, `div`, `section`, `body` etc that forms the main structure of the HTML document.

- Attributes: Every element on the web page has attributes, such as `class`, `placeholder`, `size` etc.

JavaScript can now be used to:

- add, change, and remove any of the HTML elements and attributes
- add or change any of the CSS styles
- add, update, or delete the content on the website
- handle events such as clicking a button.

The DOM is not a programming language, however, without it, the JavaScript language will have no idea of how to interact with a web page.

**It is the DOM that gives JavaScript the superpower to access and manipulate the structure, content, and appearance of a web page.**

In the next section, we will explore how an HTML document is represented as the DOM

## The `Document` Object

The actual page loaded in the browser window is represented in JavaScript by the `Document` object. You can use this `object` to manipulate the HTML and CSS of the web page.

The basic elements of a `HTML` document are:

- A text header, represented with the `<h1>`, `<h2>`, `<h3>`, `<h4>`,`<h5>`,`<h6>` tags.
- A paragraph, represented with the `<p>` tag.
- An image, represented with the `<img>` tag.
- A divider, represented with the `<div>`tag etc.

You can refer to these elements in the DOM, and because each element is an `object`, it can be accessed using JavaScript, to enable you to modify the web page.

Modifying the web page entails changing the text content, applying new styles to it, creating new HTML elements and adding them to the current element as children, or even deleting elements on the web page.

To achieve the above, the DOM comprises a set of APIs listed in the `Document` object. It has properties, methods, and events useful for manipulating and creating web pages.

For instance, the `Document.documentElement` property helps us to refer to any HTML element on the web page. Again, the `document.body` is an object representing the `<body>` element, you can use this method to manipulate the body of the `HTML` document.

Soon we’ll learn more ways to manipulate the DOM, but first, we need to know about its structure.

## Understanding the DOM tree

Whenever the HTML document is loaded in the browser window, the DOM structures the `HTML` file like a genealogical tree or family tree.

In a family tree, at the top you have the **grandparents**, followed by your **parents** and their **siblings**, then you and your **siblings** and **cousins**.

![FamilyTree](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i86xqfqyehohnq0255o2.jpeg)

Similarly, the DOM will represent all the elements in the HTML document like a family **tree** structure. Each entry in the tree is a node, and each node contains an element on the web page.

The majority of nodes in a DOM tree will be `Element` and `Text` nodes. The nodes in the node tree have a hierarchical relationship to each other.

Every tree begins with the root node, beneath, you would have head and body elements. Below the body elements, you may find the `header`, `main` and `footer` elements.

Consider the HTML source code below:

```
<!doctype html>
<html>
  <head>
    <title>DOM Manipulation</title>
  </head>
  <body>
    <h1>What is DOM</h1>
    <p>This article explain what the DOM is</p>
    <p>DOM allows you to manipulate web pages</p>
    <button>View DOM </button>
  </body>
</html>
```

The diagram below illustrates the DOM derived from the HTML above

![DOM Tree](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kgeinw3la1d6e15i092l.png)



Referencing the image above:

- Each blue and yellow circle in the diagram represents a `node`. The blue represents an `element` node whilst the yellow represents a `text` node.
- Every tree begins with the `root` node, which is the html element. From the root node, you can branch into other nodes.
- Whenever a node, has another node inside it, the initial node is called a `parent node`. From the above, `html` is the parent node because we have the `head` and `body`` nodes under it. Also `body` is the parent node of `h1`, `p`, `p` and `button` elements.
- A **child node** is a node directly inside another node: `h1`, `p` and `button` are child nodes of body
- A **sibling node** is a node that sits on the same level in the DOM tree. For instance, all the blue circles in the same level are sibling nodes: `head` and `body` are siblings, as well as `h1`, `p`, `p ` and `button`
- A node anywhere inside another node is the Descendant node

- Whenever there is content in each node, it will be represented as `#text` (as displayed in the yellow circle). A text node contains only a string. It may not have children and is always a leaf of the tree. For instance title element has the text DOM manipulation
- The entire HTML document is represented by the `document` object (a node as well)

## Exploring the DOM using the Developer tools

You can explore the DOM using the developer tools in your browser, by right-clicking on a webpage and selecting "inspect" in the context menu. Using the  icon below in the left-upper corner, you can choose a node from the webpage and inspect it.

![Developer tools](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kbh9yn9ycdort571eoti.png)

![Developer Tools](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kktt53rupa3cvkzd0g8r.png)
This gives access to the DOM element in addition to the styling applied to the element. You can interact with any of the elements, and apply styling and that change will reflect on the web page.

Even though you can find elements using the developer tool, it is not preferred. 

In the next section, you will learn how to find an element in the DOM.

## Finding Elements in the DOM

You can access the DOM elements using the `Id`, `class`, `tag` and `selectors`.

The methods for accessing elements are:
- `document.getElementById(id)`
- `document.getElementsByTagName(tagName)`
- `document.getElementsByClassName(className)`
- `document.querySelector(cssSelector)`
- `document.querySelectorAll(cssSelector)`

In the next section, you will use the above methods to find any element  in the HTML document.

### Using the getElementById() method

The `getElementById()` finds an element in the HTML document with an **assigned ID**. Since element Ids are required to be unique, it provides a way to access a specific element quickly.

The syntax is as below

`document.getElementById('ElemId')`

Supposing in our HTML document you have an element with an id `firstPara`.

For instance:

`<p id="firstPara"> Let's begin with the frist paragraph </p>`

In the JavaScript file, you can access the element with that id (firstPara) and manipulate it.

```
//access element with id firstPara
const para = document.getElementById('firstPara')
```


### Using the getElementsByTagName() method

You may want to find all the paragraphs in an HTML document.

The `getElementsByTagName()` method searches the document and returns a **collection of elements with the given tag name.**

The syntax is as below:

`document.getElementsByTagName(name)`

Let's find all the `p` tags in the index.html document below:

![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t68qxlf5hubd25lixcxf.png)

Because you  want to access all the `p` elements, you use the `p` tag as the tag name hence `document.getElementsByTagName('p')`


### Using the getElementByClassName() method

The `getElementByClassName()` method allows you to locate an element with the specified class name(s). It returns an array-like object of all child elements which have all of the given class name(s).

The syntax is as below:

`document.getElementsByClassName(names)`

**Usage**

- Get all elements that have a class name of `container` in the HTML document.

`document.getElementsByClassName('container')`

- Get all elements that have a class name of `container` and `wrapper`  in the HTML document
`document.getElementsByClassName('container wrapper')`

### Using the querySelector() method

The `document.querySelector()` returns the first element within the document that matches the specified CSS selector. If no matches are found, null is returned.

The syntax is as below:

`document.querySelector('.myClass')`

Let's assume in the code snippet below, you want to access an element with the class name `container`

The screenshot below illustrate the implementation

![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ol422la930nvliyl04fe.png)

### Importance of finding elements in the DOM

Whenever you find elements using the methods above, you can improve functionality on web page either by changing the content, styling the element or adding an event listener to it.

### Creating HTML elements

Developing the user interface of websites involves adding new elements to the HTML document. These elements can be a button, an image, a paragraph, or a heading.

In this section, you will learn how to create elements in your JavaScript file and join them to other elements to help create user interfaces. For instance, you can create a paragraph element and attach a button to it.

Use the `document.createElement()` method to create an HTML element. The method accepts the HTML tag as an argument

The syntax is as below:

`document.createElement(tagName)`

The `tagName` specifies the tag to be created for instance `div`, `button`, `paragraph`,  etc.

Let's create a heading, paragraph, button and div elements in our JavaScript file using the syntax above


![Element](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mf78o2y25gsr11uztbkm.png)


Whenever an element is created, you can use the `innerText` property to add or get the text content within the element.

In the example below, we add content to the `headingOne`, `btn` and `paragraph` elements

![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1spqoi7w4tzn70bsr9zl.png)


### Adding elements to the HTML document

After creating an element, you need to add it to the parent element to gradually build the user interface. The `appendChild()` method helps you with that.

The method adds a node to the end of the list of child nodes or a specified parent node

The syntax is as below:

`parentNode.appendChild(childNode)`

The `childNode` is the element to attach to the `parentNode`

Let's attach the `paragraph` , `headingOne`, and `btn` elements to the `div` (parent node )
Next, access the `body` of the HTML document and attach the `div` to the `body` 


![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/onap5azve8i8c1cgfw02.png)
The output below displays the user interface as expected

![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ju7flbemijsarluzn5fs.png)

### Moving and removing elements from HTML Documents

In the previous section, you learn how to gradually build the user interface of a web page by creating and adding elements to the DOM.

In this section, you will learn how to move and remove elements in the DOM.

The `appendChild()` enables you to move an existing child node to a new position within the document.

In the `index.html` below, you have two unordered lists with id's `listOne` and `listTwo`respectively, you can move the first item in `listOne` (i.e HTML) to be positioned after the last item in `listTwo` (i.e MongoDB)


![JS DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ts5n3zalkykmujanxdvk.png)

Let's learn how to achieve that:

Write the following code in your JavaScript file

![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pyegwwqop5nxrumccy0q.png)

The output is as below:

![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8e8xwuzmlrpakmuxa93j.png)

- To remove a node from its parent, use the `Node.removeChild()`

In the example below, you can remove all the items from `listOne` from the `body` node.


![JS DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w8e49h870rolmpuao085.png)

The output will be 

![JS DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k9jy3dm1zv7v8gr6ydfa.png)

### Adding and getting the content of an element

Use the methods below to read and add content to an element

- `element.textContent`
- `element.innerText`
- `element.innerHTML`

- The `textContent` property returns all the text contained by an element and all of its descendants including spaces and CSS hidden text, except the tags

In the code below, you can use the `textContent` to get the text inside the `h1` element

![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hohgn8e8ymsxkcz7vbs3.png)

Output

`"This is heading one"`

If you prefer to rather **add text** to the element, you can do:

![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zm8yit3w8s33xdmelnrr.png)
- The HTML document will reload to reflect the changees

- The `innerHTML` property **gets or changes the HTML markup of an element**

The syntax below can be used to read the content of an element

 `let content = element.innerHTML;`

In the example below, you want to get the HTML markup contained in the the `ul`.

![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0mnniwgkzd6gwwvpqdom.png)


Below is how it will be implemented in our JavaScript file  using the `innerHTML` property.


![IDOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vpq988trm8o9fo69gzml.png)

The output will be

```
<li>HTML</li>
<li>CSS </li>
```


- The `innerText` property can also be used to write dynamic text on the html document. Here, text will not be interpreted as html text but a normal text. The syntax is as below

`element.innerText = "new content:`

Let's access the `h1` tag and add a text to it.

![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x04r76jwc7id579zqsyy.png)

The output will be 

![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rri25w64ea6nudg7ahk1.png)

## Styling elements with JavaScript

It is possible to manipulate CSS styles with JavaScript. The general approach is to add inline styles directly onto the elements you want to style.

Let's take a look at how to achieve that.

### Inline styling of elements

Using the `HTMLElement.style` syntax, you have access to an object containing all the CSS properties (color, background color, font size, font weight, etc)

For instance, to change the color of an element to red, you use the `color` property and assign the value.

The syntax is as below:

`HTMLelement.style.color = 'red'`

If there are hyphens (-) in the CSS property to use, for instances `-webkit-text-stroke` , you can use the array-like notation ([]) to access the property.

If there is one hyphen (-) in the property, for instance background-color, you should write it as backgroundColor

See the examples below:

```
HTMLelement.style.['-webkit-text-stock'] = 'unset';
HTMLelement.style.backgroundColor = 'red'
```

In the example below, we changed the background color of the first list to red;

![StylingDOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/va5tpywmxlor7ixaqui7.png)

The output is as below:

![JS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/knavpflm83e7jbi2z36z.png)

### Styling HTML elements with setAttribute() method.

The `setAttribute()` assigns value to an attribute on a specified HTML element.

The syntax is as below:

`HTMLelement.setAttribute(name, value)`

It accepts two arguments `name` and `value`

**The name represents the attribute you want to set on the HTML element**

**The value is a string containing the value to assign to the attribute.**

You can use the `setAttribute()` to apply a specified class on an HTML element.

See the example below,


![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1oh9h10klax7m19nipj5.png)

The CSS file section contains a `.container` class that list all the CSS properties to apply to the HTML element.

Let's review the process:

- In the JS section, we selected the `body` of the HTML document and style it using the CSS declaration in the `.container`
- Using the `setAttribute()` method, specify the attribute to set on the element, in our case it will be a `class` and then specify the value to apply on the class which will be the `.container` CSS declaration

The output is as below:

![StyleDOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/na2t9am1m4q627b6y3gw.png)

In the next section, you will learn how to find elements in the DOM based on their relation to other elements.

## Traversing the DOM

Occasionally, you need to search **upwards, downwards, or even sideways to locate elements**. This is referred to as Traversing.

**Traversing refers to "moving through", and it is the process of finding elements in the DOM tree based on their relation to other elements.**

Traversing involves starting with one selection and moving through that selection until you reach the elements you desire.

Using methods like `document.querySelector()`, `document.getElementById()` , you can access elements in the DOM tree. 
The limitation of using these methods is that they perform a full search of the DOM tree in order to locate an element.

**Wouldn't it be easier to locate a node by moving from one element to another element compared to the full search?**

### Why DOM Traversing

Assuming you want to visit the nearest pharmacy in your neighborhood, what will be the fastest and most effective way to get there?

- If you already know the location of the pharmacy, you can move from your house directly to the pharmacy.
- Alternatively, you can search for the location of the nearest pharmacy on Google Maps, then follow the given directions.

**Moving from your house to the neighboring pharmacy is the most effective and recommended approach. This analogy is equivalent to traversing the DOM, selecting one element from a neighboring element.**

If you look up the address of the nearest pharmacy using Maps, you are using the equivalent of `document.querySelector` to find elements (i.e performing a full search which is ineffective)

Whenever you have access to a given node in the DOM tree, you can access its related node in three directions:

- Downwards
- Sideways
- Upwards

### Traversing downwards

The two methods to traverse downward are:
- `querySelector` or `querySelectorAll`
- `children`

Using the `selector` method to traverse downwards

- Use the `element.querySelector` or `element.querySelectorAll` method to traverse downwards from a specified element.

- Locate a starting point (element) and then use the `querySelector()` method on the starting element to move downwards to the required element.

For instance in the code below, to locate the `h1` element, you start from the `section` and move downward.


![JS DOM Manipulation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rkruwpy4xazn62ge0xfs.png)

The output is as below:

 `<h1 class="heading">Travesing Downwards </h1>`

Let's understand the code above

- Use the `document.querySelector('.container')` to specify the element to start searching from.
- Now, that we have access to the starting point, you can move down to the required element using the `sect.querySelector('.heading')`



### Traversing downwards using the children or childNodes properties

The `children` property selects all child elements that are immediately nested in another element.

It returns a live HTMLCollection that  contains all of the child elements.

Because the HTMLCollection is an array-like object, you can use the bracket notation to select the required item.

In the example below, you have an unordered list of fruits in the `HTML` section.

In the JavaScript file, you first find the parent element and use the `children` property to move downwards to select all the `li`'s
Finally, you can now access the third item from the list


![IDOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yoypltcostgxx2vmowk2.png)

The output is as below:
`<li>Pineapple</li>`

### Traversing Upwards

You can also move up the DOM to find elements. The two methods to navigate up the DOM are:

- `parentElement`
- `closest`

- Using `parentElement` to traverse upwards

The `parentElement` allows you to move to the selected element's parent node one level up.

In the code below, we select the `ul` and move one level up to the parent element (`div`)


![DOM Traversing](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wvetb9cmhy9bgcaweaar.png)

### Traversing upwards using the closest property

The `closest` property selects an element multiple levels above the current element.

The search begins from the current element, then moves up until it reaches the `document`. During the process, whenever it reaches the element to find, it stops and returns the element.

The syntax is as below:

`const closestAncestor = Element.closest(selector)`

In the example below, we start from the `a` element and select the `div` element **multiple levels **above the `a` element.

![Traversing DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b222u1uoin3704ip3zlr.png)


### Traversing sideways

There are two methods of walking the DOM sideways:

- `nextElementSibling`
- `previousElementSibling`

- Using the `nextElementSibling` to traverse sideways

You can select the next element using the `nextElementSibling`

The syntax is as below:

`const nextElem = Node.nextElementSibling`

Let's select the next item in the list in the example below


![Traversing DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/io9k3igeimtmazcd2a3r.png)

- Using the `previousElementSibling`

You can select the previous element with `previousElementSibling` .

In the example below, we first select the second list item (Apples), then select the previous element (Mango)


![Traversing the DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uvtqibg9fadmmzz0qfdg.png)


## Introduction to Events

In the previous sections, you learned how to create and attach elements to the DOM to create the user interface. You also learned how to traverse the DOM.

In this section, you will learn how to interact with these elements to make your web page lively.

Whenever a user or browser interacts with a web page it generates an **Event**.

**Events are signals that something has happened.**

Examples of events are:

- Submission of a form
- Resizing the browser window
- Selecting, clicking, or hovering over certain elements, etc.

These events can be categorized into `mouse`, `keyboard`, and `window` events.

**Example of Mouse events:**
- `click` – when the mouse clicks on an element
- `contextmenu` – when the mouse right-clicks on an element.
- `mouseover / mouseout` – when the mouse cursor comes over / leaves an element.
- `mousedown / mouseup` – when the mouse button is pressed/released over an element.
- `mousemove` – when the mouse is moved.

**Example of Keyboard events:**

- `keydown and keyup` – whenever a keyboard key is pressed and released.

**Example of Window events:**

- `onload`: fired when the whole page has loaded
- `onunload` : when the page has unloaded or the browser window is closed onafterPrint etc

### Event handler

To react to the event, you attach an **event handler function,** that listens for that event happening. Whenever the event occurs, for instance, a form is submitted, the event handler function runs in response to the event happening.

The body of the  event handler function contains a block of code detailing the actions to take.

Below are several ways to assign a handler

- `HTML attribute`
- `DOM Properties`
- `addEventListeners`

In this section, we will focus on using the `addEventListener` method.

### Using the addEventListener() method

The `addEventListener()` is a built-in method that enables you to handle events.

Below is the syntax:

`element.addEventListener(event, handler, [options])`;

- `event`: represents the event name. Eg. click, scroll, submit, etc
- `handler`: represents the handler function
- `options`: additional options object with properties

To remove the handler, use the `removeEventListener`.

The syntax is as below:

`element.removeEventListener(event, handler, [options]);`

**Let's target the button element on a web page and listen for a click of the button.**

When the event occurs, the handler function will be called in response to the event.

In this example below, the function will log "button clicked" to the console.


![Event handlers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hr67ccehef59ses88fwg.png)

### Passing events as arguments

Whenever you need additional information on the event, such as the element clicked, or get the value in an input field when a form is submitted, you need to pass the global `event` object as an `argument` to the handler function. 

The `event` object contains numerous properties (`type`, `target`, `currentTarget`, etc).

The example below uses `event.currentTarget` to return the element whose event listener triggered the event


![Event handler](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z3uq0iw4xweoyq918qrm.png)




## Active learning: Building the "Hey Buddy" app

In this section, you will consolidate the knowledge gained to build a "Hey Buddy" app. It is a basic contact list application that **displays the full name and phone number of your favorite buddies.**

_It is recommended that as you follow along, actively type all the code snippets in your text editor. This will help build muscle memory and fluency._

Let's look at the general approach to building the app

- You will have three files in your project directory, an `index.html`, `style.css` and `index.js` file.

- The `index.html will contain the basic boilerplate, an `h1`, `span` `ul` and `form` elements.
- All the other required elements will be built using JavaScript. 

- You will create the following elements using JavaScript:

- `input`,`div` ,`button`,`li`,`h1` and `p`
- The `form` will be nested with two `input` elements. The first handle the name of the contact, and the next input handles the phone number

- To learn how to listen for events, you will attach an `eventhandler` function to the form. On submission, you will fetch the name and contact values from the inputs and display them  as a list inside the `ul`.

- You will append a "remove button" to the every submitted contact, and attach another `eventListener` to the button. This will enable you to remove the submitted contact from the `DOM`.

- Finally, you will use the styles declared in the `style.css` file to style your application. This will enable you learn how to use the `setAttribute` property to apply styling using JavaScript.

Let's get started.

### Setting up the Project Directory

Open your favorite editor, and in your project directory, create the following files `index.html` , `index.js`, `style.css`

Link the `index.js` and `style.css` to your `index.html` file

Open the `index.html`, type the following code snippet into it:

![HeyBuddy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0nm3l22fcghq409xn3bv.png)


This index.html file contains the `form` and `ul` elements enclosed within the `main` tag.

The file also has a `section` with the heading **Hey Buddy** 

### Selecting elements from the DOM

Next, in the `index.js` file, you will select the `form` and `ul` tags from the `DOM`.

Write the following code snippet in your `index.js` file:


![DOM Tutorials](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tq55ltk7ndaniboegk56.png)

### Creating the required elements

The `form` should contain `div`'s , `label`'s , `input` 's and a `button` element.

- The `input` elements will accept data from the user.The first input will accept the **full name **of your buddy
The second input will accept the **phone number**.

- The `label` 's provide captions for the inputs whiles the `button` will help in submission of the form.

Let's create these elements in our `index.js` file

![JS DOM Tuts](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v8rh3cx3adif8u0fnrn5.png)


### Setting attributes on the elements

Attributes provide additional information on elements. 

The `setAttribute()` method is used to set or add an attribute to a particular element and provide a value to it.

You will set the following attributes on our `input` elements:

- `type`: the type attribute specifies the type of input to create. Because you will be entering the full name of your buddy in the first input, it will be a `text` input whiles the second input becomes a `number` input.

- `placeholder`: The placeholder attribute specifies a short hint that describes the expected value of an input field. You will set the placeholder value for the `text` input to "Please enter the name of buddy" and that of the phone number to "Enter the phone number of buddy"

- You will also add a `name` attribute to the `inputs`. Generally, the `name` attribute is used to handle input value after form submission. It can also be used to reference an element in Javascript.

- Set the value on the `name` attribute on the `text` input to `name`, and that of the `number` input to `contact`.

The code snippet for the above instructions is as below, kindly include them in your `index.js` file.


![DOM Tuts](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bw81p6252t4f8yrlfcuo.png)

### Adding content to the elements

Next, you will add text to the `label`'s for visual cues, and a text on the `button` element to instruct the user to click the button to submit the form.

The `innerText` property is used to set or get the text content of an element. In this example, you want to set the content of the `label` and `button` element.

To achieve that, add the below snippet to the `index.js` file


![JS DOM Tuts](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ni3cuvili1dg1294l2g3.png)

### Attaching elements to the DOM

In the previous sections, you created the required elements and set the attributes on these elements. You also added text to the labels and the button.

In this section, you will attach these elements to the form to create the user interface of the app.

Whenever elements are attached to the parent node in the DOM, the web page will reload to reflect these additions.

Let's attach the created elements to the parent node (element) using the `appendChild()` method.

- First, you want a label for the inputs, you will later attach the label to a `div`.

To achieve that follow the instructions below:

- Select the `nameLabel` element and attach it to the `nameInput`

- Select the `nameDiv` and attach the `nameLabel`

- Select the `contactLabel` and attach the `contactInput`

- Select the `contactDiv` and attach the `contactLabel`

The code snippet is as below

![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7hwr8tq5t7r52ifpxamz.png)

Next, you attach both the `nameDiv` and `contactDiv` to the `form`. Then, you attach the button to the form


![DOM JS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m4k694dxwhffzjlaq8hj.png)
The entire code snippet for the above steps is as below


![DOM JS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijyeqwgqzxbfbm6b7w2k.png)

Below is how the HTML structure will look like

![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rhjr7gj4mh9e36a2zkec.png)


Then on our web page, you will notice the elements have been displayed

Let's focus on the functionality for now, the styling will be dealt with later.

![DOM JS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gmn1wvfofasauikmgb8w.png)

In the next section, you will focus on creating the elements that will help us display the data from the inputs.

### Creating the additional user interface

You will declare a `createBuddy` function, and in the body of the function, you will create the following elements:

`li`, `h2`, `p` and `button`

You will use the `ul` tag in the `index.html` together with the `li` to create a list.

This list will contain the contact name and phone number represented by the h2 and p elements  respectively.

The `button` element will help remove the contact details from the `DOM`.

Type the code below into the body of the `createBuddy` function.


![DOM Manipulation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k4mv856q4m7xh3d3v8dw.png)

### Add an event handler to the form

Next, you will get the full name, and phone number when the form is submitted, and assign their values to variables.

You will implement an event handler to handle and verify user inputs and actions. When the button is clicked, you will get the data in the input fields and assign their values to a declared variable.

Let's create an event handler function called, `handleFormSubmit`

```
//get the value from inputs on btn click 
const handleFormSubmit= (event)=>{
  event.preventDefault()
  
}
```
The `handleFormSubmit` accepts an `event` parameter.

When we call the `handleFormSubmit()`, we will pass an `event` object as an `argument`.

- The `event` object will keep track of various events that occur on the page, such as the user submitting the form, and allows you to react to them.

- The `event.preventDefault()` in the body of the function alerts the browser that if there is a default behavior for this event, then skip that default behavior.

- For example, because we will be submitting a form, the default behavior would be to submit the data to a server. However, due to the `event.preventDefault()`, the browser would not submit the form when the button is clicked. This enables us to get the values entered in the input fields and display them on the page.

Let's now attach the `handleFormSubmit` event handler to the `form`

You will attach the `handleFormSubmit` to the form with the help of the `addEventListener()` method and listen for a `submit` of the form.

The code snippet is as below:
```
form.addEventListener('submit', (e)=>handleFormSubmit(e))

```

### Fetching the data from the form

You will use the `event.currentTarget` method to reference the elements that the event handler has attached.

In our example, the `handleFormSubmit` has been attached to the two input elements.

You can now get the data entered in the input elements by referring to the name we set on the elements and using the value property to get the entered data.

Below, we get the entered data for the full name and phone number and assign them to the `buddyName` and `buddyContact` variables respectively.

```
const handleFormSubmit= (event)=>{
//prevent default submission of form 
  event.preventDefault()
//get the data entered in the input fields
  const buddyName = event.currentTarget.name.value
  const buddyContact = event.currentTarget.contact.value
  
}
```

Adding the values in the inputs to the DOM elements

Next, when we submit the form, we want to pass the values stored in the `buddyName` and `buddyContact` variables as `arguments` to the `createBuddy` function.

This will enable us to add their data as text to the `h2` and `p` elements we have in the `createBuddy`

The code snippet is as below:

```
const handleFormSubmit= (event)=>{
//prevent default submission of form 
  event.preventDefault()
//get the data entered in the input fields
  const buddyName = event.currentTarget.name.value
  const buddyContact = event.currentTarget.contact.value
 
// pass data to createBuddy  
createBuddy(buddyName,buddyContact)
}
```
The `createBuddy` function you will define later will accept `name` and `contact` as `parameters`.

In the body of the `createBuddy` function, you will use the `textContent` property to assign the values in the `name` and `contact` to the `buddyHeading` and `buddyPara` variables.

You will also add text to the `buddyBtn`

The code snippet is as below:
```
const createBuddy = (name,contact)=> {
 ... //initial code remains the same

//add the content from the inputs to the heading and paragraph
  buddyHeading.textContent = name;
  buddyPara.textContent = contact
 // add content to the button element
  buddyBtn.textContent = "remove buddy"
}
```
In the next section, you will learn how to attach these elements to the DOM

### Attaching elements to the DOM

In the previous section, you created the required elements for the contact details and assign text to them. 

In this section, you want to attach elements with their content to the DOM to build the user interface.

Follow the steps below:

- Append the `p` to the `h2`
- Append the `h2` to the `li`
- Append the `button` to the `li`
- Append the `li` to the `ul`

Add the code below to the `createBuddy` function

```
 //attach the elements to the dom
  buddyHeading.appendChild(buddyPara)
  buddyItem.appendChild(buddyHeading)
  buddyItem.appendChild(buddyBtn)
// append the li to the ul to create the unordered list
  ul.appendChild(buddyItem)
```

The entire code for this section is as below:

```
// create buddy 
const createBuddy = (name,contact)=> {
  const buddyItem = document.createElement('li')
  const buddyHeading = document.createElement('h2')
  const buddyPara = document.createElement('p')
  const buddyBtn = document.createElement('button')
  
  //add content to the elements
  buddyHeading.textContent = name;
  buddyPara.textContent = contact
  buddyBtn.textContent = "remove buddy"
 
  //attach the elements to the dom
  buddyHeading.appendChild(buddyPara)
  buddyItem.appendChild(buddyHeading)
  buddyItem.appendChild(buddyBtn)
  ul.appendChild(buddyItem)
 
}
```
Below is the user interface when data has been entered into the inputs  and the form has been submitted

![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vcidvsbe7btj83vau1fm.png)

The output in the DOM is as below:

![DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r5dzi2664vfvtebxhr0w.png)

### Clearing the form fields

You want to clear the values in the input fields whenever the form has submitted.

You will declare a `clearForm`function, and use the `reset()` method on the `form` to clear all the values in the input fields.

The code is as below:

```
//clear form field when submitted
const clearForm = ()=>{
  form.reset()
}
```
You will execute the clearForm function in the body of the `handleFormSubmit` so that whenever the form is submitted, you can  clear the inputs.

The code is as below:

```
const handleFormSubmit= (event)=>{
  ... // previous code remains the same

  //clear field values 
  clearForm()
  
}
```

### Removing the contact from the DOM

Finally, you can choose to delete any of our favorite buddy from the contact list. This action will remove the item from the DOM as well

To achieve that, you will use the `removeChild()` method.

This method removes a child node from the parent node.

In this tutorial, the `ul` is a **parent node** and the `li` is **child node.**

Because the contact details are in the `li`, you will attach an event handler to the "remove buddy" button.

Whenever the button is clicked, you will remove the `li` from the `ul` in effect removing the contact details.

The code snippet is as below:

```
//remove buddy on button click
const removeBuddy = (item, btn )=> {
  btn.addEventListener('click',()=>{ ul.removeChild(item)})
}
```

Let's call the `removeBuddy` inside the `createBuddy` function, so that you can pass the `buddyItem` and `buddyButton` as arguments to the `removeBuddy`

```
// create buddy 
const createBuddy = (name,contact)=> {
... // previous code remains the same
 //pass item and button as arguments
  removeBuddy(buddyItem, buddyBtn)
}
```
The entire code for all the above steps is as below:
```
// select the elements from the Document
const form = document.querySelector('form');
const ul = document.querySelector('ul')

//create label elements
const nameLabel = document.createElement('label')
const contactLabel = document.createElement('label')

//create input elements
const nameInput = document.createElement('input')
const contactInput = document.createElement('input')

//create div elements
const nameDiv = document.createElement('div')
const contactDiv = document.createElement('div')

//create button element.
const btn = document.createElement('button')



//set Attributes on elements
nameInput.setAttribute('type','text')
nameInput.setAttribute('placeholder', 'Please enter name of buddy')
nameInput.setAttribute('name', 'name')

//set attributes on the contact
contactInput.setAttribute('type', 'number')
contactInput.setAttribute('placeholder','Enter phone number of buddy')
contactInput.setAttribute('name', 'contact')

//add content to  the labels
nameLabel.innerText = "Buddy name"
contactLabel.innerText = "Buddy contact"


//add text to the button 
btn.innerText = "Add buddy"


//attach the created elements to the form 
nameLabel.appendChild(nameInput)
nameDiv.appendChild(nameLabel)

contactLabel.appendChild(contactInput)
contactDiv.appendChild(contactLabel)

form.appendChild(nameDiv)
form.appendChild(contactDiv)
form.appendChild(btn)

// create buddy elements
const createBuddy = (name,contact)=> {
  const buddyItem = document.createElement('li')
  const buddyHeading = document.createElement('h2')
  const buddyPara = document.createElement('p')
  const buddyBtn = document.createElement('button')
  
  //add content to the elements
  buddyHeading.textContent = name;
  buddyPara.textContent = contact
  buddyBtn.textContent = "remove buddy"
  
  //add class to the button
  buddyBtn.setAttribute('class', 'removeBtn')
  //attach the elements to the dom
  buddyHeading.appendChild(buddyPara)
  buddyItem.appendChild(buddyHeading)
  buddyItem.appendChild(buddyBtn)
  ul.appendChild(buddyItem)
 
  //remove item from list on button click
  removeBuddy(buddyItem, buddyBtn)
}


//clear form field when submitted
const clearForm = ()=>{
  form.reset()
}

//get the value from inputs on btn click 
const handleFormSubmit= (event)=>{
  event.preventDefault()
  const buddyName = event.currentTarget.name.value
  const buddyContact = event.currentTarget.contact.value
 // call create items
  createBuddy(buddyName,buddyContact)
  //clear field values 
  clearForm()
  
}
//submit the form
form.addEventListener('submit', (e)=>handleFormSubmit(e))


//remove buddy on button click
const removeBuddy = (item, btn )=> {
  btn.addEventListener('click',()=>{ ul.removeChild(item)})
}
```

### Styling the app

Let's now focus on styling our web app.

In the `style.css` we have declared all the required selectors and their corresponding CSS properties.

```
 @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600&display=swap');

* {
  box-sizing: border-box;
  margin: 0;
  padding:0;
  font-family: 'Poppins', sans-serif;
}
header {
  display:grid;
  place-items:center;
  color: #361D2E;
  margin-top:2rem;
  
}
header > h1 {
  padding: 1rem;
  font-size: 3rem;
  font-weight: 600;
}
header > h1 > span {
  font-weight: 100;
}
header > p {
  font-size: 1.2rem;
  margin-bottom: 2rem;
}
.body_container {
  background-color: #F2F4CB
}
.main_container {
  width: 50vw;
  border: 5px solid #593D3B;
  border-radius: 1rem;
   padding:2rem;
}
ul {
  list-style-type:none;
  display:flex;
  flex-wrap: wrap;
  gap: 3.5rem;
  margin-top:2rem;
}
ul > li {
 background-color: #361D2E;
 padding-left: 1rem;
 padding-right: 1rem;
 border-radius: 20px;
 color: #fff;
 flex-basis: 45%
   
}
ul > li > h2 {
 font-size: 1.3rem;
 text-transform: Capitalize;
 padding: 1rem 0rem;
 font-weight: 600
 
  
}
ul > li > h2 > p {
  margin-top: 1rem;
  font-weight: 100;
  color:  #F2F4CB;
}
input {
  width: 70%;
  font-size: 1.1rem;
  border:none;
  padding: 0.5rem;
  margin: 1rem;
  border-radius:10px;
}
input[type="text"] {
  margin-left: 2.2rem;
}

.labelContent {
  font-size: 1.3rem;
}
button {
  font-size: 1.2rem;
  border:none;
  outline:none;
 
}
.addBtn {
   background-color: #593D3B;
  color: #fff;
  margin: 1rem 0rem;
  padding:1rem;
  border-top-left-radius: 20px;
  border-bottom-right-radius: 20px;
}
.addBtn:hover, .addBtn:active {
  background-color: #8A7968;
  cursor: pointer;
  transition: all 0.5s ease-in;
}
.removeBtn{
  background-color: #8A7968;
  margin: 1.5rem 0rem;
  color: #fff;
  padding:0.5rem;
  width: 100%;
  border-radius: 10px;
}
.removeBtn:hover, .removeBtn:active {
  cursor: pointer;
  background-color: #fff;
  color: #361D2E;
  transition: all 0.5s ease-in
}
```
A quick look at what has been implemented

- Import the Poppins font from Google
- Define the background color of the app in the `body-container` class
- Declared the style for the `input` elements, `buttons`, `labels`, `li`'s etc.

Now, the task is to dynamically style our app using JavaScript.

- First, select the `body` element and apply the `body_container` class to it using the `setAttribute` property

```
const body = document.querySelector('body')

body.setAttribute('class','body_container')
```

Next, select the `input` elements, and using the `setAttribute` and apply the required class to it.

```
nameInput.setAttribute('class','inputFields')
contactInput.setAttribute('class', 'inputStyling')
```

Select the `label` elements, and apply the required class to it

```
//label
nameLabel.setAttribute('class', 'labelContent')
contactLabel.setAttribute('class','labelContent')
```

Finally, select the `button` element, and style it

```
btn.setAttribute('class','addBtn')
```

Below is the output of the web app after applying the styles and submitting the form

![JS tuts](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ezvhsxgxkkorlicwglua.png)

The source code to the tutorial is as below
{% codepen https://codepen.io/efkumah/pen/rNqJpQa %} 


### Summary

In this article, you learn that

- The Document Object Model (DOM) is a tree-like representation of the content of the web page
- It is the DOM that gives JavaScript the superpower to access and manipulate the structure, content, and appearance of a web page.
- Access the DOM elements using the `Id`, `class`, `tag` and `selectors`.
- Use the `document.createElement()` method to create an HTML element
- Add elements to the DOM using `parentNode.appendChild(childNode)`
- Style HTML elements with the `setAttribute()` method.

If you have found value in this article, or what to provide some feedback, please do leave your comment. I am looking forward to reading your messages. Don't forget to also share this article on your social media handles, to reach more audience.

Till then, keep learning, keep growing !