Удаление div по нажатию кнопки при динамическом добавлении/удалении

Есть форма динамического добавления инпута посредством вписывания названия лейбла и нажатия кнопки Add filter.

Иерархия формы такая:

form
├── div
│    ├── button
│    ├── label
│    └── input
├── div
│    ├── button
│    ├── label
│    └── input
├ ...
...

button - Кнопка для удаления div

label - Название для input

input - Само поле ввода

Мне нужно чтобы по нажатию на button удалялся весь div. То есть по факту сделать кнопку удаления поля ввода.

У меня были мысли изложенные в коде, при добавлении label прописать ему в innerHTML строку с созданием button и добавлением ему id таким образом:

 label.innerHTML = `<button id="remove-filter-${filterToAdd.value}">&times</button>${filterToAdd.value}`

Отсюда рождается проблема, что чтобы добавить универсальный .onclick нужен id div который надо удалить, тогда можно было бы прописать как-то вот так:

const removeButton = document.getElementById('remove-filter')

removeButton.onclick = e => {
    e.preventDefault()

    mainForm.removeChild(сюда вставить объект)  

Однако, если я в лейбле создаю уникальный идентефикатор для button, то есть к примеру ```id="remove-filter-${filtertoAdd.value}" то я не смогу сделать уникальный кусок для удаления дива.

Можно сделать уникальный id- remove-filter, но тогда нужно как-то получить id от объекта который я хочу удалить.

const initialForm = document.getElementById('initial-form')
const addFilterButton = document.getElementById('add-filter')
const mainForm = document.getElementById('main-form')
const filterToAdd = document.getElementById('filter-for-add')
const addRemoveField = document.getElementById('add-remove-field')

const presentFilters = []

initialForm.addEventListener('submit', e => {
    e.preventDefault()

    if (document.getElementById('remove-filter') && presentFilters.length === 0) {
        addRemoveField.removeChild(document.getElementById('remove-div'))
    }

    if (filterToAdd.value.length !== 0 && !presentFilters.includes(filterToAdd.value)) {
        presentFilters.push(filterToAdd.value)

        const div = document.createElement('div')
        const input = document.createElement('input')
        const label = document.createElement('label')

        label.innerHTML = `<button id="remove-filter-${filterToAdd.value}">&times</button>${filterToAdd.value}`
        label.setAttribute('for', `${filterToAdd.value}`)

        input.type = 'text'
        input.setAttribute('id', `${filterToAdd.value}`)

        div.id = 'input-div'
        div.appendChild(label)
        div.appendChild(input)

        mainForm.appendChild(div)

        filterToAdd.value = ''
    }
})
body {
    background-color: #303030;

    font-family: 'Courier New', Courier, monospace;

    display: flex;  
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

#initial-form {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

#filter-input-label {
    margin-top: 30px;

    color: white;
    letter-spacing: 3px;
}

#filter-for-add {
    background-color: rgb(71, 71, 71);
    
    font-family: 'Courier New', Courier, monospace;
    color: white;

    padding: 3px 8px;

    border: none;
    border-radius: 5px;
    border-bottom: 2px solid orangered;
    border-bottom-left-radius: 5px;
    border-bottom-right-radius: 5px;
}

#filter-for-add:focus {
    outline: none;
}

#add-remove-field {
    display: flex;
    flex-direction: row;
    justify-content: space-evenly;
    align-items: center;
    gap: 50px;
}

#add-filter {
    background-color: transparent;
    transition: background-color ease 0.1s;
    
    color: white;

    border: 1px solid orangered;
    border-radius: 3px;

    padding: 5px 10px;
    margin-top: 40px;
    margin: 40px 10px 0 10px;

    transform: scale(1.3)
}

#add-filter:hover, #remove-filter:hover {
    background-color: orangered;
    transition: background-color ease 0.1s;

    cursor: pointer;
}

#main-form {
    display: grid;
    grid-template-columns: 1fr;
}

#input-div {
    display: flex;
    flex-direction: column;

    margin: 15px 15px;
}

#input-div label {
    color: white;
}

#input-div input {
    background-color: rgb(71, 71, 71);
    transition: background-color ease 0.1s;

    color: white;
    font-family: 'Courier New', Courier, monospace;

    padding: 5px 10px;

    border: none;
    border-bottom: 1px solid orangered;
    border-radius: 3px;
    border-bottom-left-radius: 3px;
    border-bottom-right-radius: 3px;
}

#input-div input:focus {
    outline: none;
}

#input-div button {
    background-color: transparent;
    transition: background-color ease 0.1s;

    color: white;

    border: 1px solid orangered;
    border-radius: 3px;

    padding: 2px 6px;
    margin-right: 10px;
    margin-bottom: 5px;
}

#input-div button:hover {
  background-color: orangered;
  transition: background-color ease 0.1s;
  
  cursor: pointer;
}
<!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>Document</title>

        <link rel="stylesheet" href="../font-awesome-4.7.0/css/font-awesome.min.css">
        <link rel="stylesheet" href="./df.css">
    </head>
    <body>
        <form id="initial-form">
            <label id="filter-input-label" for="filter-for-add">Filter: </label>
            <input type="text" id="filter-for-add" list="initial-input-variants">
            <datalist id="initial-input-variants">
                <option>HostName</option>
                <option>ProdName</option>
                <option>ProcName</option>
                <option>ProdCode</option>
                <option>Customer</option>
                <option>tLogIn</option>
            </datalist>
            
            <div id="add-remove-field">
                <button type="submit" id="add-filter">Add filter <span>+</span></button>
            </div>
        </form>

        <form id="main-form"></form>

        <script src="./df.js"></script>
    </body>
</html>


Ответы (2 шт):

Автор решения: ksa

Мне нужно чтобы по нажатию на button удалялся весь div. То есть по факту сделать кнопку удаления поля ввода.

Как вариант...

const of = document.querySelector('form')
document.querySelector('#add').addEventListener('click', e => {
  const html = `
  <div>
    <button>Del</button>
    <label>Item 2</label>
    <input />
  </div>
  `
  of.insertAdjacentHTML('beforeend', html)
})
of.addEventListener('click', e => {
  const o = e.target
  if (o.tagName != 'BUTTON') return
  // дабы форма не отправилась
  e.preventDefault()
  o.closest('form').removeChild(o.closest('div'))
})
<button id='add'>Add</button>
<form>
  <div>
<button type='button'>Del</button>
<label>Item 1</label>
<input />
  </div>
  <div>
<button type='button'>Del</button>
<label>Item 2</label>
<input />
  </div>
  <div>
<button type='button'>Del</button>
<label>Item 3</label>
<input />
  </div>
  <div>
<button type='button'>Del</button>
<label>Item 4</label>
<input />
  </div>
</form>

→ Ссылка
Автор решения: SwaD

Вот пример реализации динамического добавления и удаления блоков.

Код добавления взят из вашего примера.

В код добавлено создание события нажатия на кнопку, которая вызывает удаление div

const add = document.getElementById('addButton');
const divFerma = document.getElementById('divFerma');
let numFilters = 0;

add.addEventListener('click', () => {
  const idx = numFilters++;
  const div = document.createElement('div');
  const btn = document.createElement('button');
  const inp = document.createElement('input');
 
  btn.innerHTML = `Удалить ${idx}`;
  inp.value = `Поле ${idx}`;
  // Создаем событие нажатия на кнопку
  btn.addEventListener('click', () => {
    div.remove();
  })
  div.appendChild(inp);
  div.appendChild(btn);
  divFerma.appendChild(div);
});
<div id='divFerma'></div>
<br />
<button id='addButton'>Добавить +</button>

→ Ссылка