Markdownでコードはブロック内に正しく書いてください。非常に見にくいです。
2点押さえておきたいところがあります。
まず、createElementで作られたエレメントは使い回しが効きません。コレが原因の1つです(cloneNodeでもアリですが、idなどの様々な重複事故を未然に防ぐという意味でおすすめしません)。
<table>タグ内は本来、<thead>や<tbody>が必要ですが、これらの記載を省略するとブラウザが勝手に追加してくれます。この時点で追加されない要因の、もう1つの原因を作っています。
https://developer.mozilla.org/ja/docs/Web/HTML/Reference/Elements/thead
https://developer.mozilla.org/ja/docs/Web/HTML/Reference/Elements/tbody
そして、<tbody>の件(勝手に作られる)が絡んでくると、JSの最後のtbl.appendChild(tr);のアプローチが間違っています。
document.getElementById('tbl')はidがtblとなっているテーブルエレメントを返すので変数tblはHTMLTableElementに化けます。
このHTMLTableElementにはtBodiesというプロパティを持っているので、最初の0個目(<tbody>は複数の記載が認められるため)を指定してからappendChildしなければなりません。つまり
tbl.tBodies.item(0).appendChild(tr);
となります。
そういったトラブルを少なくするにはHTML側も正しく記載する必要があります。
<div id="main">
<table id="tbl">
<thead>
<tr>
<th>商品選択</th><th>注文数</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
手直しするとこういう感じにはなります。
See the Pen
Untitled by えむ a.k.a. STSynthe (@stsynthe)
on CodePen.
const itemList = [
'商品を選んで下さい',
'商品A',
'商品B',
'商品C'
];
const createSelectElement = () => {
const select = document.createElement('select');
for (const text of itemList) {
const option = document.createElement('option');
option.text = text;
select.add(option);
}
return select;
};
const createInputElement = () => {
const input = document.createElement('input');
input.type = 'tel';
input.placeholder = '注文数を『単位』で入力';
return input;
};
const tbl = document.getElementById('tbl');
for (let i = 0; i <= 4; i++) {
const tr = document.createElement('tr');
const tdLeft = document.createElement('td');
const tdRight = document.createElement('td');
tdLeft.appendChild(createSelectElement());
tdRight.appendChild(createInputElement());
tr.appendChild(tdLeft);
tr.appendChild(tdRight);
tbl.tBodies.item(0).appendChild(tr);
}
あと、変数宣言にvarの使用はできるだけ避けるべきです(事故の元になりやすい)。