I'm having some trouble figuring out how to add elements to a parent object on a click event.
The result that i'm hoping to achieve is this:
<ul>
<li><button>B1</button>
<ul class="newul">
<li><button>B1.1</button>
<ul class="newul">
<li><button>1.1.1</button></li>
<li><button>1.1.2</button></li>
</ul>
</li>
<li><button>B1.1</button></li>
</ul>
</li>
<li><button>B2</button></li>
<li><button>B3</button></li>
</ul>
Let's say I click button B2. I want a new UL added to the parent LI of that button and then be able to add new LI elements to the newly created UL. I hope that makes sense!
So basically, click button, add new UL with class "newul" to the LI you're currently in -> add new LI's to that newly created UL.
The jquery I'm currently using is as follows:
$('button').click(function(){
//Get parent..
var parent = $(this).parent();
//Add a new UL to the parent and save it as newul
var newul = parent.add("ul");
//Add the class to the new UL
newul.addClass('newul');
//Add a new li to the new UL
newli = newul.add('li');
//Add a button to the new LI
newli.append('<button></button>');
});
Unfortunately, this is having completely undesired effects and sticks buttons everywhere all over the place. I'd appreciate any help you can offer.
Here's a visible example of what i'm after. The top part is the effect id like to achieve.
Example of desired result
Even though @am not i am has the correct code. There is no explanation of why your code fails, and I think that's the answer you are asking for.
There are several problems in your code:
First
//Add a new UL to the parent and save it as newul
var newul = parent.add("ul");
The 'ul'
is a selector and so is going to search the DOM for other <ul>
elements, rather than create a new one. Also, parent.add()
method is returning the parent
object, not the ul's that you selected.
Correct code:
//Add a new UL to the parent and save it as newul
var newul = $("<ul>").appendTo(parent);
Second:
//Add a new li to the new UL
newli = newul.add('li');
Same problem again, and since newul
is actually still the parent
you're getting all types of craziness. Also, you're missing a var
, but maybe I just don't get your closure.
Correct code:
//Add a new li to the new UL
var newli = $("<li>").appendTo(newul);
That's all. If you fix that in your code, it'll work.
However, unless you really need those references to persist, better performance is usually achieved if you pass the whole thing as a string:
$('button').click( function() {
$(this).parent()
.append(
$('<ul class="newul"><li><button></li></ul>')
);
});
And if you wanted all the new buttons to have the same functionality, use the on()
method and a class for your buttons:
$('body').on('click', 'button.ul-appending', function() {
$(this).parent()
.append(
$('<ul class="newul"><li><button class="ul-appending"></li></ul>')
);
});
You could change the 'body'
selector to something much more specific so this doesn't get queried on every click on your page. Just make sure to add the class ul-appending
to all the existing buttons that aren't generated by this handler.
One issue I see here is that the new buttons created will not have the click event bound to them. I fix this by using on
and setting the event as a delegate. In doing so I give the outer ul
an id
of container
. I also check to make sure you haven't already added a ul
element and append one if it isn't inside the li
. Here is a working example.
$('#container').on("click", "button.newbtn", function(){
var parent = $(this).closest('li');
var childUl = parent.children('ul');
if(childUl.length === 0) {
parent.append("<ul class='newul'></ul>");
childUl = parent.children('ul');
}
childUl.append($("<li><button class='newbtn'>" + $(this).html() + "." + (childUl.children().length + 1) + "</button></li>"));
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With