I've found good posts on good practices inserting dom elements using jquery like this, this and this
It's ok when you just need to insert a few elements, but it seems to me that these option are very bad from the point of view of maintainability (Code is repeated twice, thus if any change is needed it needs to happen twice then it becomes very prone to error ),
This is (just a small part) what I've got
<script type="text/javascript">
var phnFragment = "<tr><td align=\"right\">Telephone:</td><td colspan=\"2\"><select name=\"select\" size=\"1\"style=\"width: 100px;\"><option>-- Choose --</option><option>Home</option><option>Mobile</option><option>Work</option></select><input type=\"text\" size=\"20px\" /></td></tr>";
$(document).ready(function() {
$('#addmorephones').click(function() {
$("#phones").append(phnFragment);
});
});
</script>
....
....
<tr id="phones">
<td align="right">Telephone:</td>
<td colspan="2"><select name="select" size="1"
style="width: 100px;">
<option>-- Choose --</option>
<option>Home</option>
<option>Mobile</option>
<option>Work</option>
</select><input type="text" size="20px" /> <a href="javascript:void(0);" id="addmorephones">[+]</a>
</td>
</tr>
Is there a better way to accomplish this? Is there a way to tell jquery to copy part of the dom tree and use it as fragment to insert?
Would love to learn alternatives
Is there a way to tell jquery to copy part of the dom tree and use it as fragment to insert?
Yes: clone
. (You don't even really need jQuery for it; cloneNode
is part of the DOM API.) If you have any id
values in what you clone, you'll need to iterate over the result changing them, of course, since id
s have to be unique. But it's perfect for things like table rows and the like.
On page load, you can grab one of the real ones, clone it (without attaching it to the document), cleanse it of anything you don't need, and then just keep cloning that model. Helps keep your JavaScript somewhat decoupled from your markup.
Example:
HTML:
<table>
<tbody>
<tr><td>I'm a row in the table</td></tr>
</tbody>
</table>
JavaScript:
jQuery(function($) {
var counter = 10,
rowModel;
// Get the row model, clone it, remove the
// content we'll replace anyway.
rowModel = $("tr:first").clone();
rowModel.find("td:first").empty();
// Do our first tick
tick();
// Use the model to append to the table
function tick() {
var clone = rowModel.clone();
clone.find("td:first").html("Added at " + new Date());
$("tbody:first").append(clone);
// Again?
if (--counter > 0) {
setTimeout(tick, 500);
}
}
});
Obviously that's a quick-and-dirty, but you get the idea. If you use data-xyz
attributes (allowed in HTML5), name
s, class
es, etc., you can avoid tying your code too closely to your structure.