13

Here is the code:

$('#date').append(
    '<select id="date">'+
    '<option value="0">- - SELECT - -</option>');
    for(var i in data){
    $('#date').append(
    '<option value="">'+data[i]['date_time']+'</option>');
    });
$('#date').append('</select>');

</select> is always added above for loop. If i replace it with just work select for example, it is appended at the end, where it should be. Why is this happening and how can i fix it?

Gagandeep Singh
  • 5,755
  • 4
  • 41
  • 60
Milos911
  • 433
  • 3
  • 9
  • 21
  • please describe the `strange behaviour`? – xdazz Jan 23 '12 at 09:17
  • Have you considered closing first append before second append statement? :) – Gagandeep Singh Jan 23 '12 at 09:17
  • 1
    It looks like you might have more than one element with the same `id`, which is invalid. You are calling `append` on `#date`, and then creating a new element that would match `#date`. – James Allardice Jan 23 '12 at 09:19
  • I followed one of the answers and found solution. Thanks, i have fixed double id issue (it would pass unnoticed if you didnt mentioned it to me). "Have you considered closing first append before second append statement?" Closing how? :) – Milos911 Jan 30 '12 at 21:55

5 Answers5

6

I believe that jQuery will generate the DOM like this:

<div id="date">
    <select id="date">
        <option value="0">- - SELECT - -</option>
    </select>
    <option value="">foo</option>
    <option value="">bar</option>
    etc...
</div>

Since it is automatically closing the <select> after the first .append(). What you are doing afterwards is appending the options to the <div id="#date"/> rather than the <select> that was appended. I don't think the final closing </select> will actually do anything either.

If you really want to use append the following JavaScript will add the options to the correct node:

// dummy data object for example
var data = new Array(new Array(), new Array());
data[0].date_time = 2011;
data[1].date_time = 2012;

var options = new Array();
$.each(data, function(index, option) {
    options.push('<option value="' + index + '">'+ option.date_time +'</option>');
});

$('<select id="date"/>').append(options.join('')).appendTo('#date');

Assuming the existing HTML:

<div id="date"></div>

However this does incur an overhead since appending is occurring twice. The faster approach is to build up the options markup as already answered by ShankarSangoli

andyb
  • 43,435
  • 12
  • 121
  • 150
4

It is not the right way to create html dynamically. You should create the complete markup all at once by putting it into an array and then provide it to jQuery. Try this

var html = [];
html.push('<select id="date">');
html.push('<option value="0">- - SELECT - -</option>');
for(var i in data){
   html.push('<option value="">'+data[i]['date_time']+'</option>');
}
html.push('</select>');
//This selector should be some container like dateContainer
//because you have already give date as id to the above select element
$('#dateContainer').html(html.join(''));
ShankarSangoli
  • 69,612
  • 13
  • 93
  • 124
2
$('#date').append($("<select/>", { name: "name"+i})
 .find('select')   
 .append($("<option/>", { value: "abc"+i}).text('cell'))   
 .append($("<option/>", { value: "abc"+i}).text('home'))   
 .append($("<option/>", { value: "abc"+i}).text('work'));

all options should wrap inside select

m90
  • 11,434
  • 13
  • 62
  • 112
Nitin
  • 49
  • 3
  • You would still need to filter the initial selection by chaining in a `.find('select')` – m90 Mar 20 '12 at 13:25
0

If you want to do it in your way - create, for example, string variable with html code in it and than append it.

data = [1, 2, 3];
var html = '<select id="date">'+
    '<option value="0">- - SELECT - -</option>';
 for(var i in data){
    html += '<option value="">'+data[i]+'</option>';
}
$('#date').append(html)

or look here What is the best way to add options to a select from an array with jQuery?

ps: the first append tries to create a valid DOM structure inside of document, closing select tag automatically. that is why the second one will not insert options into the created select.

another possible way, based on the link above, is

var sel = $('<select id="date">');
$.each(data, function(key, value) {   
       sel.append($('<option>').text(key['date_time'])); 
});
$('#date').append(sel);
Community
  • 1
  • 1
Cheery
  • 16,063
  • 42
  • 57
0

I imagine the base HTML you have looks something like this:

<div id="date"></div>

then after the first $('#date').append('<select id="date">... in your code, you will have this:

<div id="date"><select id="date">...</div>

which is 2 elements with the same ID attribute.

The ID attribute is like the highlanders, there must only be one of them (in each page).

The seccond $('#date').append... works unexpectedly, and the 3rd one, also unexpectedly, doesn't work. Because you can't predict to which #date they are referring.

Also, as the other answers say, it will be better if you build it to do only 1 append, because calling the selectors so many times (especially inside the loop) it's a performance hit.

maeghith
  • 101
  • 1
  • 4