Reputation: 55
I have a button on my page, and when I push it I want to append a new div (with 2 more divs inside it, plus some extra p-tags).
Here is what I want to happen:
<div id="mainDiv" draggable="true" ondragstart="drag(event)">
<div class="subDiv1">
<p class="p1">text</p>
<p class="p2">text</p>
</div>
<div class="subDiv2">
<p class="p3">text</p>
</div>
</div>
but I get this result instead:
<div id="mainDiv" draggable="true" ondragstart="drag(event)">
<div class="subDiv1"></div>
<p class="p1">text</p>
<p class="p2">text</p>
<div class="subDiv2"></div>
<p class="p3">text</p>
</div>
Obviously its something wrong with the code below but I can't figure out what. Should I use appendTo instead of append, and in that case where?
$(document).ready(function() {
$("#addButton").click(function() {
var divToAdd =
$('<div id="mainDiv" draggable="true" ondragstart="drag(event)"></div>')
.append('<div class="subDiv1">')
.append('<p class="p1">text</p>')
.append('<p class="p2">text</p></div>')
.append('<div class="subDiv2">')
.append('<p class="p3">text</p></div>');
$('.whereToAddDivs').append(divToAdd);
Upvotes: 2
Views: 1048
Reputation: 10216
the jQuery .append() function returns the initial element that you call .append() on, not the newly appended element. That means, $().append().append().append() will always act as a chain of appends to your $() element.
In your case, you must append like so:
$(document).ready(function() {
$("#addButton").click(function() {
var divToAdd =
$('<div id="mainDiv" draggable="true" ondragstart="drag(event)"></div>')
.append($('<div class="subDiv1"></div>').append('<p class="p1">text</p>').append('<p class="p2">text</p>'))
.append($('<div class="subDiv2"></div>').append('<p class="p3">text</p>'));
$('.whereToAddDivs').append(divToAdd);
Upvotes: 0
Reputation: 136104
You requirement is nested, but your code is not. Just match your required nesting with your code:
var divToAdd = $('<div id="mainDiv" draggable="true" ondragstart="drag(event)"></div>')
.append(
$('<div class="subDiv1">').append('<p class="p1">text</p>')
.append('<p class="p2">text</p>')
)
.append(
$('<div class="subDiv2">').append('<p class="p3">text</p></div>')
);
$('.whereToAddDivs').append(divToAdd);
Live example: http://jsfiddle.net/SRJHY/
And as for your little confusion at the end regarding appendTo
, you can use it to negate the last line in your example code to append the newly created div
to your container like so:
$('<div id="mainDiv" draggable="true" ondragstart="drag(event)"></div>')
.append(
$('<div class="subDiv1">').append('<p class="p1">text</p>')
.append('<p class="p2">text</p>')
)
.append(
$('<div class="subDiv2">').append('<p class="p3">text</p></div>')
)
.appendTo('.whereToAddDivs');
Live example: http://jsfiddle.net/LQJbz/
Upvotes: 0
Reputation: 119837
Because you are appending it one after the other into the #mainDiv
. What you want to happen is to append the p
first to their respective #subDiv
and then append them to #mainDiv
.
//your main div
var mainDiv = $('MAIN_DIV_HTML');
//creating subdivs and append to mainDiv
var subDiv1 = $('SUB_DIV1_HTML').appendTo(mainDiv);
var subDiv2 = $('SUB_DIV2_HTML').appendTo(mainDiv);
//the first set of p's appending to subdiv 1
var p1 = $('P1_HTML').appendTo(subDiv1);
var p2 = $('P2_HTML').appendTo(subDiv1);
//the next set of p's to subdiv2
var p3 = $('P3_HTML').appendTo(subDiv2);
//append everything
$('.whereToAddDivs').append(mainDiv);
I also suggest you research on templating solutions instead of this "html in js" approach. Mustache and Handlebars should be good for starters.
Upvotes: 1
Reputation: 129792
append
appends one DOM node to another. If you supply a HTML string it tries to create a DOM node out of that. Appending an open DIV tag without matching end tag isn't going to create an unclosed DIV node because there's no such thing, so your first append creates a full DIV. You then need to append to that.
I usually generate nodes in this manner:
$('<div />', { id: 'mainDiv', draggable: 'true', ondragstart: 'drag(event)' })
.append($('<div />', { 'class': 'subDiv1' })
.append($('<p/>', { 'class': 'p1', text: 'text' }))
.append($('<p/>', { 'class': 'p2', text: 'text' }))
)
.append($('<div />', { 'class': 'subDiv2' })
.append($('<p/>', { 'class': 'p3', text: 'text' }))
)
.appendTo('.whereToAddDivs');
Upvotes: 1
Reputation: 388316
Try
var divToAdd =
$('<div id="mainDiv" draggable="true" ondragstart="drag(event)"></div>')
.append($('<div class="subDiv1" />').append('<p class="p1">text</p>').append('<p class="p2">text</p>'))
.append($('<div class="subDiv2"/>').append('<p class="p3">text</p>'))
;
Upvotes: 0
Reputation:
Why use several appends? You can do it that way, but why not do this:
$('<div id="mainDiv" draggable="true" ondragstart="drag(event)"></div>')
.append('<div class="subDiv1"><p class="p1">text</p><p class="p2">text</p></div><div class="subDiv2"><p class="p3">text</p></div>');
This is faster, and less prone to error. If you really need to use several appends, you need to append each child to the correct parent. Your existing method appends all the child elements to #mainDiv.
Upvotes: 0