tags:

views:

6329

answers:

4

I would like to create a DOM node, set the 'id' attribute and then append it to 'body'. The following seems not to work because jQuery doesn't see my template as an object. How can I tell jQuery to treat it as an object so find() works on it?

var template = "<li><div class='bar'>bla</div></li>";

template.find('li').attr('id','1234');

$(body).append(template);

+4  A: 

I'd put it in the DOM first. I'm not sure why my first example failed. That's really weird.

var e = $("<ul><li><div class='bar'>bla</div></li></ul>");
$('li', e).attr('id','a1234');  // set the attribute 
$('body').append(e); // put it into the DOM

Putting e (the returns elements) gives jQuery context under which to apply the CSS selector. This keeps it from applying the ID to other elements in the DOM tree.

The issue appears to be that you aren't using the UL. If you put a naked li in the DOM tree, you're going to have issues. I thought it could handle/workaround this, but it can't.

You may not be putting naked LI's in your DOM tree for your "real" implementation, but the UL's are necessary for this to work. Sigh.

Example: http://jsbin.com/iceqo

By the way, you may also be interested in microtemplating.

altCognito
You're setting the attribute after the object has been appended... My tests say this doesn't work.
bart
Yeah, it broke for me as well. Weird. I thought I had run it through. Anyway, this version works.
altCognito
This version works fine.
altCognito
It works, but if your body has more than one 'li' then the attribute is added to all of these... Maybe adding :last will do.
bart
No it won't, that's why the e is there to specify context.
altCognito
See http://docs.jquery.com/Core/jQuery#expressioncontext
altCognito
Oh hell, it didn't use the context. What a day.
altCognito
Don't understand, you DO set the contents: $('li',e), but that doesn't do anything...
bart
+4  A: 

Try this:

var div = $('<div></div>').addClass('bar').text('bla');
var li = $('<li></li>').attr('id', '1234');
li.append(div);

$('body').append(li);

Obviously, it doesn't make sense to append a li to the body directly. Basically, the trick is to construct the DOM elementr tree with $('your html here'). I suggest to use CSS modifiers (.text(), .addClass() etc) as opposed to making jquery parse raw HTML, it will make it much easier to change things later.

DrJokepu
This doesn't add the element, I'm guessing because of the body tag, you have to quote it.
altCognito
Oh yeah I forgot about that, sorry. Fixed now.
DrJokepu
A: 

First make your template into a jQuery object:

 var template = $("<li><div class='bar'>bla</div></li>");

Then set the attributes and append it to the DOM.

 template.find('li').attr('id','1234');
 $(document.body).append(template);

Note that it however makes no sense at all to add a li directly to the DOM since li should always be children of ul or ol. Also it is better to not make jQuery parse raw HTML. Instead create a li, set its attributes. Create a div and set it's attributes. Insert the div into the li and then append the li to the DOM.

Pim Jager
I would think that _sshould_ work, but it doesn't. (it's in fact exactly what I posted first) see: http://jsbin.com/eware
altCognito
I confirm, it doesn't work :(
bart
A: 

And here is the one liner:

$("<li><div class='bar'>bla</div></li>").find("li").attr("id","1234").end().appendTo("body")

But I'm wondering why you would like to add the "id" attribute at a later stage rather than injecting it directly in the template.

gizmo
This doesn't work, we've been down the road before. I'm wondering if it's a bug, because it really seems like it ought to work, and a number of people have ran into this .
altCognito
It works, look at the example: http://jsbin.com/izeko/
gizmo