简体   繁体   中英

Vanilla JS to dynamically add or remove div boxes

When checking on the checkbox i'm trying to create the div boxes and when unchecking remove it dynamically.

I know with React i could do this in 2min but i'm trying to learn Vanilla JS way

Current issues i'm having:

  1. When checking on checkbox it renders more elements than one
  2. When unchecking checkbox for example all one element is still rendered.

END GOAL: dynamically add and remove Div boxes depending on what is in state variable, ( console.log that its outputting should give guidance on how correctly it should look) but also making sure no extra boxes are being used / rendered.

 window.onload = () => { const checkbox = document.querySelectorAll('.checkbox') let state = [] for (idx of checkbox) { idx.addEventListener('change', (e) => { if (e.currentTarget.checked === true) { state.push(e.currentTarget.id) renderOnDom(state, 'add', e.currentTarget.id) // Experimenting } if (e.currentTarget.checked === false) { state = state.filter((item) => item !== e.currentTarget.id) renderOnDom(state, 'remove', e.currentTarget.id) // Experimenting } console.log('state', state) }) } } const renderOnDom = (el, option, id) => { if (option === 'add') { el.map((item, idx) => { const div = document.createElement('div') div.setAttribute('key', item) div.className = 'test' div.innerHTML = `Box ${item}` document.querySelector('#projects').appendChild(div) }) } if (option === 'remove') { const test = document.querySelectorAll('.test') const prod = document.querySelector('#projects') for (const iterator of test) { if (iterator.attributes.key.value === id) { prod.removeChild(prod.firstChild) } } } }
 <input id="id1" data="name1" class="checkbox" type="checkbox" /> <label for="id1">Test 1</label> <input id="id2" data="name2" class="checkbox" type="checkbox" /> <label for="id2">Test 2</label> <input id="id3" data="name3" class="checkbox" type="checkbox" /> <label for="id3">Test 3</label> <div id="projects"></div>

Hey I have updated your snippet to do what I think you want to do.

In a nutshell, the source of truth is state array. So after any changes to it, reset the dom using resetDom() and then fire renderOnDom() .

 window.onload = () => { const checkbox = document.querySelectorAll('.checkbox') let state = [] for (idx of checkbox) { idx.addEventListener('change', (e) => { if (e.currentTarget.checked === true) { state.push(e.currentTarget.id) } if (e.currentTarget.checked === false) { state = state.filter((item) => item !== e.currentTarget.id) } renderOnDom(state, e.currentTarget.id) }) } } const resetDom = () => { const projects = document.querySelector("#projects"); while (projects.firstChild) { projects.removeChild(projects.firstChild) } } const renderOnDom = (el, id) => { resetDom(); el.forEach((item, idx) => { const div = document.createElement('div') div.setAttribute('key', item) div.className = 'test' div.innerHTML = `Box ${item}` document.querySelector('#projects').appendChild(div) }) }
 <input id="id1" data="name1" class="checkbox" type="checkbox" /> <label for="id1">Test 1</label> <input id="id2" data="name2" class="checkbox" type="checkbox" /> <label for="id2">Test 2</label> <input id="id3" data="name3" class="checkbox" type="checkbox" /> <label for="id3">Test 3</label> <div id="projects"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM