Tag literal example

2012-12-12

Just wanted to give a quick example on why I would love for some kind of tag literal syntax to be added to JS. I'm creating a simple table. The why, why I'm doing it in JS, and the fact that you'd consider it bad are all completely irrelevant.

This is the html I'm trying to create in JS:

Code:
<table>
<tr>
<td></td>
<td style="text-align:center;"><button></button></td>
<td></td>
</tr>
<tr>
<td><button></button></td>
<td>
<input style="width:50px;"/> x <input style="width:50px;"/>
</td>
<td><button></button></td>
</tr>
<tr>
<td></td>
<td style="text-align:center;"><button></button></td>
<td></td>
</tr>
</table>

Could potentially combine the tds in the top and bottom rows, but whatever. This is the JS I end up with:

Code:
var up = document.createElement('button');
var down = document.createElement('button');
var left = document.createElement('button');
var right = document.createElement('button');
var w = document.createElement('input');
w.style.width = '50px';
var h = document.createElement('input');
h.style.width = '50px';

var table = document.createElement('table');
var tbody = document.createElement('tbody');
for (var j=0; j<3; ++j) {
var tr = document.createElement('tr');
for (var i=0; i<3; ++i) {
var td = document.createElement('td');
if (i == 1 && j == 0) td.appendChild(up);
if (i == 0 && j == 1) td.appendChild(left);
if (i == 2 && j == 1) td.appendChild(right);
if (i == 1 && j == 2) td.appendChild(down);
if (i == 1 && j == 1) {
td.appendChild(w);
td.appendChild(document.createTextNode(' x '));
td.appendChild(h);
}
if (i == 1 && j != 1) td.style.textAlign = 'center';
tr.appendChild(td);
}
tbody.appendChild(tr);
}
table.appendChild(tbody);
document.body.appendChild(table);

Meh.

So let's look at what this would look like if we could use tag literals in JS:

Code:
var table = <table>
<tr>
<td></td>
<td style="text-align:center;"><button></button></td>
<td></td>
</tr>
<tr>
<td><button></button></td>
<td>
<input style="width:50px;"/> x <input style="width:50px;"/>
</td>
<td><button></button></td>
</tr>
<tr>
<td></td>
<td style="text-align:center;"><button></button></td>
<td></td>
</tr>
</table>;

document.body.appendChild(table);

And with handles to the right elements:

Code:
var up = <button/>;
var down = <button/>;
var left = <button/>;
var right = <button/>;
var width = <input style="width:50px;"/>;
var height = <input style="width:50px;"/>;

var table = <table>
<tr>
<td></td>
<td style="text-align:center;">{up}</td>
<td></td>
</tr>
<tr>
<td>{left}</td>
<td>{width} x {height}</td>
<td>{right}</td>
</tr>
<tr>
<td></td>
<td style="text-align:center;">{down}</td>
<td></td>
</tr>
</table>;

document.body.appendChild(table);

(Note that if you paste this in my demo, the dynamic elements are stringified, something I intend to fix but haven't so far.) Siiighhh... so much better. If only..

If you haven't already, check out my tag literal demo. See also Ian Hickson's "HTML literals in JS" strawman, which proposes pretty much what I've demoed.