Sibi Sibi - 2 months ago 8
CSS Question

Newly added elements using jQuery doesn't have it's CSS applied correctly

I use jQuery to dynamically add new elements. But the newly added element doesn't have it's CSS applied properly.

I have demonstrated my problem with the jsFiddle. The newly added input text box has different spacing between them.

HTML Code:

<fieldset>
<div class="control-group custom">
<label class="input-mini" for="first">Start</label>
<label class="input-mini" for="first">End</label>
<label class="input-mini" for="first">Share</label>
</div>
<div class="control-group custom">
<input type="text" class="input-mini">
<input type="text" class="input-mini">
<input type="text" class="input-mini">
</div>
<div>
<a id="plus_time_button" class="btn plus" href="#">
<i class="icon-plus-sign"></i>
</a>
</div>
</fieldset>


JS Code:

$("#plus_time_button").live("click", function () {
var new_row = "<div class=\"control-group custom\"><input type=\"text\" class=\"input-mini\"><input type=\"text\" class=\"input-mini\"><input type=\"text\" class=\"input-mini\"></div><div><a id=\"plus_time_button\" class=\"btn plus\" href=\"#\"><i class=\"icon-plus-sign\"></i></a></div>";
$("fieldset div:last-child").remove();
$("fieldset").append(new_row);
});


CSS Code:

.custom label {
padding: 4px 6px;
margin-right: 20px;
display: inline-block;
text-align: center !important;
}
.custom input {
margin-right: 20px;
}


There is a somewhat similar question but it doesn't help me.

Answer

Spaces.

Your original HTML uses code like this:

<input ...>
<input ...>

Your added HTML uses code like this:

<input ...><input ...>

The whitespace between tags in the first results in a little extra space (the... size of a space) between tags, which the added rows lack.

A couple strategies:

Broadly, you can avoid annoying whitespace interference like this like so:

<input type=text class=input-mini
><input type=text ...

The trailing angle bracket wraps to the next line to consume all the whitespace.

But, what you really ought to be doing here is reusing the same DOM elements in the added rows as you use in the originals, so there's no difference row to row.

An approach I often use:

http://jsfiddle.net/b9chris/3Mzs2/17/

Create a single row template - I like to use an id of "T":

<div id=T class="control-group custom">
  <input type=text class=input-mini>
  <input type=text class=input-mini>
  <input type=text class=input-mini>
</div>

Get the template row and remove its id, then just clone it whenever you need to add one - that way whatever HTML you happened to use in the original, gets reused in your appends:

var plus = $('#plus_time_button').closest('div');
var T = $('#T');
T[0].id = '';

for(var i = 0; i < 3; i++)
    plus.before(T.clone());

$('#plus_time_button').click(function () {
    plus.before(T.clone());
});

My original answer used your existing event syntax, with .live(). Converting to the jQuery 1.9 syntax isn't necessary since you're presumably still on 1.7 or 1.8, but if you'd like, the code above does away with live (it actually discards it entirely since it isn't necessary any longer - the tag in question is never removed from the DOM). Examples for converting .live() calls for 1.9 are provided in the jQuery documentation:

http://api.jquery.com/live/#entry-longdesc