javascripthtmldominnerhtmlinnertext

innerText not showing after setting it straight after creating the element


I'm making a react component for selecting and deselecting tags. For this is want the tags to be shown in a table, with a checkbox next to them. My issue is that I can't set the text part of it, when creating them through JavaScript. Neither through innerHTML nor innerText. It shows in the inspector, but not in my browser (Chromium).

So far my method looks like this:

generateTagTable() {
    let tbl = document.getElementById('tagTable')
    tbl.className = 'tagTable'
    let tbdy = document.createElement('tbody')
    for (let i = 0; i < this.allTags.length; i++) {
        let tr = document.createElement('tr')
        let td = document.createElement('td')
        let div = document.createElement('div')
        let cb = document.createElement('input')
        div.className = 'checkContainer'
        cb.id = 'checkTd'
        cb.type = 'checkbox'
        cb.innerText = 'Tag'
        div.appendChild(cb)
        td.appendChild(div)
        tr.appendChild(td)
        tbdy.appendChild(tr)
    }
    tbl.appendChild(tbdy)
}

Which results in this:

enter image description here

I know that I can achieve my goal by doing the this:

generateTagTable() {
        let tbl = document.getElementById('tagTable')
        tbl.className = 'tagTable'
        let tbdy = document.createElement('tbody')
        for (let i = 0; i < this.allTags.length; i++) {
            let tr = document.createElement('tr')
            let td = document.createElement('td')
            td.className = 'checkContainer'
            td.innerHTML = '<div class="flexcenter"><input type="checkbox" name="tagCheck"/>' + this.allTags[i] + '</div>'
            tr.appendChild(td)
            tbdy.appendChild(tr)
        }
        tbl.appendChild(tbdy)
    }

But that leaves me with problem when trying to assign the onClick, and generally leaves me with less control I feel.

The result of the working one is this, and what i'm trying to achieve is this:

enter image description here


Solution

  • Checkboxes (input elements in general) don't have content (they're void elements), so innerText and textContent and innerHTML don't have any function in relation to them.

    If you want text next to your checkbox, the usual thing is to wrap a label around it. In markup, that would be:

    <label>
        <input type="checkbox">
        Text
    </label>
    

    Adjusting your code, you might do:

    // ...
    let td = document.createElement('td')
    let div = document.createElement('div')
    let label = document.createElement('label')  // *** (added)
    label.innerText = 'Tag'                      // *** (moved and modified)
    let cb = document.createElement('input')
    div.className = 'checkContainer'
    cb.id = 'checkTd'
    cb.type = 'checkbox'
    label.insertBefore(cb, label.firstChild);    // *** (added)
    div.appendChild(label)                       // *** (modified)
    // ...
    

    That said, it would be much simpler via markup (tr.innerHTML = ...), and browsers are very fast parsing markup.

    // ...
    let tr = document.createElement('tr')
    tr.innerHTML = `
        <td>
            <div class="checkContainer">
                <label>
                    <input type="checkbox" id="checkTd">
                    Tag
                </label>
            </div>
        </td>`;
    tbdy.appendChild(tr)
    // ...
    

    Side note: As it stands, your code creates multiple input elements with the same id (checkTd). That's invalid, only one element in a document can have that id. Depending on what you're doing, you may not need an id at all, or you may need to add a suffix to it (perhaps using i) to make it unique.