Create An Element In TypeScript

4 min read

Table of Contents:

Title Image for the Article

TypeScript is a superset of JavaScript. It gives JS some extra functionality. Let's learn how to make elements on the DOM in TypeScript.

Introduction

You are creating a frontend design and you want to have the user to add an extra form input. Instead of them having to request a new form from the server they can just request the frontend to create it saving time and energy!

Setup

Open your terminal and create a folder that you want the project to exist in. Once open, ensure that you have Node JS installed on your computer.

Don't have NodeJS? Install it here!

Technologies that will be used in this:

  • Node JS
  • Node Package Manager
  • Snowpack
  • Bootstrap CSS
  • TypeScript

The npm init command will run you through the basic setup of a project. You can hit enter all the way through unless you want to customize the options (not required for this project).

Snowpack will be used as a bundler to handle the change from TypeScript to JavaScript.

npm init
npm install snowpack
npx snowpack init
npm i @snowpack/plugin-typescript typescript

Package.json

We will add some custom commands to our package.json:

{
  "name": "createelementts",
  "version": "1.0.0",
  "description": "Create an element using TypeScript",
  "main": "index.js",
  "scripts": {
    "start": "snowpack dev",
    "build": "snowpack build"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "snowpack": "^3.8.8",
    "typescript": "^4.4.4"
  },
  "dependencies": {
    "@snowpack/plugin-typescript": "^1.2.1"
  }
}

The commands added were "snowpack dev" and "snowpack build"

Now we will add some folder structure get everything together and make sure it runs!

Create a src folder and add an "index.ts" and then at the root of the project add an index.html:

Index.ts

In your index.ts add:

console.log('connected');

Index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Create an Element in TypeScript</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>
<body>
    <h1>Hello world!</h1>
    <script src="src/index.js"></script>
</body>
</html>

Run it

Open up your termainl and execute:

npm run start

This should start your server and you will see Hello World! (Check the console to ensure you see "connected").

Creating the Layout

What we are going to add to the html document is the container. It is going to be a section of a form that you can use to add multiple pet names. Something you might see on an apartment website for registering animals.

...
<div class="container">
        <div class="row">
            <div class="col-3"></div>
            <div class="col-6">
                <form>
                    <fieldset>
                        <legend>Name of your pets:</legend>
                        <div id="petContainer">
                            <div class="mb-3">
                                <div class="container">
                                    <div class="row">
                                        <div class="col-8">
                                            <input class="form-control" type="text" name="petName" placeholder="PetName" aria-label="Pet Name"/>
                                        </div>
                                        <div class="col-4">
                                            <button class="btn btn-danger removeBtn" type="button">Remove</button>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="mb-3">
                            <button id="addPetBtn" type="button" class="btn btn-success">Add</button>
                        </div>
                    </fieldset>
                </form>
            </div>
            <div class="col-3"></div>
        </div>
    </div>
...

Now that the html is made, we will not interact with it anymore. All the logic and the rest of the project will be handled in the TypeScript file.

The TypeScript

The first thing we are going to do is setup our document selectors to grab the HTML. This acts as a way for our TypeScript to talk with the HTML document.

const petContainer = document.getElementById('petContainer') as HTMLDivElement;
const addPetBtn = document.getElementById('addPetBtn') as HTMLButtonElement;
const firstRemoveBtn = document.querySelector<HTMLButtonElement>('button.removeBtn');

The top two selectors are used to grab the button and the div element that will hold all of our pet form inputs. The addPetBtn grabs the button so we can apply logic.

The final item is the first form input that is loaded in will need the same event listener as the rest of the dynamically created ones.

The first thing we are going to do is generate the new form item. In TypeScript (and JavaScript) creating an item can go two ways. You can create a template literal (which is just typing it out like HTML with backticks) or generating it using the DOM methods in the browser.

For this project we will use the DOM methods to create our items; while it is more typing work, it helps use maintain better control over each item.

The Create Function()

const createPetFormInput = (): HTMLDivElement => {
    const addPetDiv = document.createElement('div') as HTMLDivElement;
    addPetDiv.classList.add('mb-3');
    const addPetDivContainer = document.createElement('div') as HTMLDivElement;
    addPetDivContainer.classList.add('container');
    const addPetDivRow = document.createElement('div') as HTMLDivElement;
    addPetDivRow.classList.add('row');
    const addPetDivCol8 = document.createElement('div') as HTMLDivElement;
    addPetDivCol8.classList.add('col-8');
    const petNameInput = document.createElement('input') as HTMLInputElement;
    petNameInput.classList.add('form-control');
    petNameInput.setAttribute('type', 'text');
    petNameInput.setAttribute('name', 'petName');
    petNameInput.setAttribute('placeholder', 'Pet Name');
    petNameInput.setAttribute('aria-label', 'Pet Name');
    const addPetDivCol4 = document.createElement('div') as HTMLDivElement;
    addPetDivCol4.classList.add('col-4');
    const removePetBtn = document.createElement('button') as HTMLButtonElement;
    removePetBtn.classList.add('btn', 'btn-danger', 'removeBtn');
    removePetBtn.setAttribute('type', 'button');
    removePetBtn.innerHTML = 'Remove';
    removePetBtn.addEventListener('click', () => {
        addPetDiv.remove();
    })
    // Appending
    addPetDiv.append(addPetDivContainer);
    addPetDivContainer.append(addPetDivRow);
    addPetDivRow.append(addPetDivCol8, addPetDivCol4);
    addPetDivCol8.append(petNameInput);
    addPetDivCol4.append(removePetBtn);
    return addPetDiv;
}

This function will generate the HTML Node to be put on the DOM. The key advantage of this is the event selector is added internally to the remove button. The code will not have to navigate the DOM it can call on the parent element and we know for a fact it is removing the correct item within its scope.

Final Part of the Code

Now we just have to add two event listeners and our project will work!

addPetBtn.addEventListener('click', (): void => {
    petContainer.append(createPetFormInput());
});
firstRemoveBtn!.addEventListener('click', (): void => {
    firstRemoveBtn?.parentElement?.parentElement?.parentElement?.remove();
})

We can just call our function to append to the container element. The other event listener just adds to the other way to remove the element. We traverse the DOM upwards to remove the correct parent element.

The reason I do not have the TypeScript just dynamically create it on load is for web crawlers. Everything you generate in JavaScript might not show up in a web crawler (they just read the HTML and link tags).

Conclusion

That is it for the code! Play around with it, break it, and turn it into something you can use! Have a great evening!

Recent Articles

Push Weight with Python

Create a simple terminal application that can let you know how much weight you need to put on the ba...

Validate Forms in TypeScript

Relying on HTML to validate your forms is just one step in ensuring visitors enter their information...

Automation with NodeJS

NodeJS can help you automate simple tasks. Being a web developer you can achieve the same goals as o...

Automation with Python

Python can take boring tasks away from you so you can continue to do other things. It is a scripting...

Speed With Cache in WordPress

Most WordPress sites use Apache as their server. Apache has a lot of tools built into it to speed up...

Social Media