views:

226

answers:

3

jQuery: how to create a new div, assign some attributes, and create an id from some other elements attributes?

How can I accomplish this. What I've tried below is not working and I'm unsure how to make it work.

What I'm trying to do is create a div and assign it some attributes, then append this div to all the < li > elements that are the on the last node of my unordered list. And lastly, but most important I want to retrieve the value of the attribute called "p_node" from the < li > that is being appended to and insert it in as part of the ID of the newly created div.

Here's my current jQuery code:

$('<div />,{id:"'+ $("#nav li:not(:has(li))").attr("p_node").val() +'_p_cont_div", class:"property_position"}').appendTo("#nav li:not(:has(li))");

Here's the HTML before the div creation:

<ul>
    <li p_node="98" class="page_name">Category A</li>
</ul>
<ul>
    <li p_node="99" class="page_name">Category B</li>
</ul>

Here's what I want it to look like after the new div creation:

<ul>
    <li p_node="98" class="page_name">Category A</li>
    <div id="98_p_cont_div" class="property_position"></div>
</ul>
<ul>
    <li p_node="99" class="page_name">Category B</li>
    <div id="99_p_cont_div" class="property_position"></div>
</ul>

Update

This works:

$("#nav li:not(:has(li))").each(function () {
    var self = $(this);
    p_node = self.attr(\'p_node\');
    self.after("<div  class=\'property_position\' />");
});

This doesn't work:

$("#nav li:not(:has(li))").each(function () {
    var self = $(this);
    p_node = self.attr(\'p_node\');
    self.after("<div id=\'" + p_node + "\' class=\'property_position\' />");
});

This also doesn't work:

$("#nav li:not(:has(li))").each(function () {
    var self = $(this);
    p_node = self.attr(\'p_node\');
    self.after("<div class=\'property_position\' />");
    $("li>div").attr("id",p_node);
});
+1  A: 

You want to append a different element to each li.

The best way to do this is to call append with a generator function, like this: (Untested)

$("#nav li:not(:has(li))").append(function(index, html) { 
    return $('<div />', {
        id:    $(this).attr("p_node").val() + '_p_cont_div', 
        class: "property_position"
    });
});

Alternatively, you can keep your current code, then call attr on the newly-inserted <div>s with a function that checks the parent attribute.

SLaks
Thanks for the help. But for some reason I couldn't get this to work. Thanks for your help anyway.
Ronedog
class is a reserved word. try className or quotes around class.
meder
+1  A: 

I went for:

$('selector').each(function () {
    var self = $(this);

    self.after('<div id="' + self.attr('p_node') + '_p_cont_div" class="property_position" />');
});

I couldn't work out what elements you want this to be performed on.

The problem you have at the moment is that you're adding exactly the same element to each UL, as you're first generating the element, and then adding it repeatedly.

(Selector would need to match the LI, but the code could be adapted to match something else.)

Matt
+1 - I'm with you, this is what I thought up, I just didn't know exactly how he wanted it implemented.
Jud Stephenson
This implementation is great and works, with one exception. The div gets properly inserted, but there is a problem with the id attribute. I've tried various string contatenations, but can't seem to figure anythingout. I'm sure it's something simple.if I do this : p_node = self.attr(\'p_node\'); self.after("<div id=p_node class=\'property_position\' />");I get this:<div class="property_position" id="p_node"></div>This doesn't let jquery run: self.after("<div id=\'" + p_node +"\' class=\'property_position\' />");
Ronedog
I also tried this:self.after("<div class=\'property_position\' />");$("li>div").attr("id",p_node);why does this not work? It doesn't make sense...is it because the div hasn't been created in the dom at this point?
Ronedog
Can you post the whole thing that you're using again? It works fine for me.
Matt
see my post below.
Ronedog
+1  A: 

It's a syntax error, try:

$("#nav li:not(:has(li))").each(function () {
    var self = $(this);
    p_node = self.attr('p_node');
    self.after("<div id='" + p_node + "' class='property_position' />");
});

This one has a syntax error, and a wrong selector:

$("#nav li:not(:has(li))").each(function () {
    var self = $(this);
    p_node = self.attr('p_node');
    self.after("<div class='property_position' />");
    self.next().attr('id', p_node);
});

But you're still missing the "_p_cont_div" part of the id, so how about:

$("#nav li:not(:has(li))").each(function () {
    var self = $(this);
    p_node = self.attr('p_node');
    self.after("<div id='" + p_node + "_p_cont_div' class='property_position' />");
});

But then we're heading back to what I originally posted:

self.after('<div id="' + self.attr('p_node') + '_p_cont_div" class="property_position" />')
Matt
I must be an idiot...but I can't fix this...see my other post with more code examples. thanks.
Ronedog
Matt, Forget what I've said...although it is still a problem, I couldn't figure out why the php output messed things up. So, I took the <script> that was put in a php string and moved all the jquery/javascript code into my .js file and called a javascript function directly...and it works now. Hope this makes sense for anyone else who comes along.So, in the end your solution was what I needed...thanks. I just needed to put it into a .js file and run it that way.
Ronedog
Meh, your PHP output should work if you use `self.after( \'<div id="\' + self.attr(\'p_node\') + \'_p_cont_div" class="property_position">Something</div> \' );`
Matt