How to remove list item from Typescript todo list app

  angular, css, html, javascript, typescript

I am attempting to build a basic todo list app using ONLY Typescript, HTML, and CSS. app.ts is set up to listen for a submit event. The ListTemplate class defines a render method used to create and append the list item elements to the DOM. The ListItem class defines listItem as a string type and executes the format() function defined in the HasFormatter interface. List items are dynamically appended to <ul></ul> container in the HTML. The functionality to input text and append list items to the DOM currently works fine. I am now trying to append functioning remove item buttons to each list item, which I set up in the render method: const btn = document.createElement('button'). I am not sure how to set up the functionality to remove individual list items when clicking the remove buttons. I tried adding another event listener to app.ts that listens for the remove button with the id listItemBtn, but am not sure how to set up the listener (or potentially a remove method in ListTemplate) to target specific list items when clicking remove button. Any thoughts on how to do this? Thanks!

app.ts

import { ListItem } from './classes/ListItem.js';
import { ListTemplate } from './classes/ListTemplate.js';
import { HasFormatter } from './interfaces/HasFormatter.js'

const form = document.querySelector('#newForm') as HTMLFormElement; // typecasting, casting the element to be a certain type
const listItemBtn = document.querySelector('#listItemBtn') as HTMLButtonElement;
const listItem = document.querySelector('#listItem') as HTMLInputElement;

//list template instance
const ul = document.querySelector('ul')!;
const list = new ListTemplate(ul)

form.addEventListener('submit', (e: Event) => {
    e.preventDefault();

    let values: [string] // tuple
    values = [listItem.value]

    let doc: HasFormatter;

    doc = new ListItem(...values)

    list.render(doc, listItem.value, 'start')
})

listItemBtn.addEventListener('onclick', (e: Event) => {
    e.preventDefault();
???
}

ListTemplate.ts

import { HasFormatter } from "../interfaces/HasFormatter.js";

export class ListTemplate {
    constructor(private container: HTMLUListElement){}

    render(item: HasFormatter, heading: string, position: 'start' | 'end'){
        const li = document.createElement('li');

        const p = document.createElement('p');
        const btn = document.createElement('button');
        btn.appendChild(document.createTextNode('x'));
        btn.setAttribute('id', 'listItemBtn')
        p.innerText = item.format();
        li.append(p);
        li.append(btn)

        if (position === 'start'){
            this.container.prepend(li);
        } else {
            this.container.append(li);
        }
    }

    remove() {
        ???
    }
}

ListItem.ts

import { HasFormatter } from '../interfaces/HasFormatter.js'

export class ListItem implements HasFormatter { //ensuring that all structures follow HasFormatter structure
    constructor(
        public listItem: string
    ) {}

    format() {
        return `${this.listItem}`
    }
}

HasFormatter.ts

export interface HasFormatter {
    format(): string
}

index.html

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>TypeScript Tutorial</title>
  <!-- <link rel="stylesheet" href="styles.css"> -->
</head>
<body>

  <header>
    <form id="newForm">
      <div class="field">
        <label>List item</label>
        <input type="text" id="listItem">
      </div>
      <button>Add</button>
    </form>

    <div class="wrapper">

      <!-- output list -->
      <ul class="item-list">
        
      </ul>
    </div>
  </header>

  http://app.js
</body>
</html>

Source: Angular Questions

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.