Dodanie opcji do wyboru za pomocą javascript

161

Chcę, aby ten javascript tworzył opcje od 12 do 100 w zaznaczeniu z id = "mainSelect", ponieważ nie chcę ręcznie tworzyć wszystkich tagów opcji. Czy możesz dać mi kilka wskazówek? Dzięki

function selectOptionCreate() {

  var age = 88;
  line = "";
  for (var i = 0; i < 90; i++) {
    line += "<option>";
    line += age + i;
    line += "</option>";
  }

  return line;
}
Kuba Rozpruwacz
źródło
14
Głosowanie za ponownym otwarciem, ponieważ połączony „duplikat” ma tylko odpowiedzi oparte na jQuery, podczas gdy ta wymaga (lub przynajmniej implikuje wymóg) prostego JavaScript.
David mówi, że przywróć Monikę
3
Świetna odpowiedź tutaj :mySelect.options[mySelect.options.length] = new Option('Text 1', 'Value1');
ruffin

Odpowiedzi:

254

Możesz to osiągnąć za pomocą prostej forpętli:

var min = 12,
    max = 100,
    select = document.getElementById('selectElementId');

for (var i = min; i<=max; i++){
    var opt = document.createElement('option');
    opt.value = i;
    opt.innerHTML = i;
    select.appendChild(opt);
}

Demo JS Fiddle .

Porównanie JS Perf zarówno mojej odpowiedzi , jak i odpowiedzi Sime'a Vidasa , uruchomiłem, ponieważ pomyślałem, że jego wyglądał na trochę bardziej zrozumiały / intuicyjny niż mój i zastanawiałem się, jak to przełoży się na wdrożenie. Według Chromium 14 / Ubuntu 11.04 kopalnia jest nieco szybsza, ale inne przeglądarki / platformy prawdopodobnie będą miały inne wyniki.


Edytowano w odpowiedzi na komentarz OP:

[Jak] [ja] zastosuję to do więcej niż jednego elementu?

function populateSelect(target, min, max){
    if (!target){
        return false;
    }
    else {
        var min = min || 0,
            max = max || min + 100;

        select = document.getElementById(target);

        for (var i = min; i<=max; i++){
            var opt = document.createElement('option');
            opt.value = i;
            opt.innerHTML = i;
            select.appendChild(opt);
        }
    }
}
// calling the function with all three values:
populateSelect('selectElementId',12,100);

// calling the function with only the 'id' ('min' and 'max' are set to defaults):
populateSelect('anotherSelect');

// calling the function with the 'id' and the 'min' (the 'max' is set to default):
populateSelect('moreSelects', 50);

Demo JS Fiddle .

I na koniec (po dość dużym opóźnieniu ...) podejście rozszerzające prototyp funkcji HTMLSelectElementw celu powiązania populate()funkcji, jako metody, do węzła DOM:

HTMLSelectElement.prototype.populate = function (opts) {
    var settings = {};

    settings.min = 0;
    settings.max = settings.min + 100;

    for (var userOpt in opts) {
        if (opts.hasOwnProperty(userOpt)) {
            settings[userOpt] = opts[userOpt];
        }
    }

    for (var i = settings.min; i <= settings.max; i++) {
        this.appendChild(new Option(i, i));
    }
};

document.getElementById('selectElementId').populate({
    'min': 12,
    'max': 40
});

Demo JS Fiddle .

Bibliografia:

David mówi, że przywróć Monikę
źródło
@Jack: zgodził się i zastosowałem to podejście w drugiej edycji :)
David mówi, że przywróć Monikę
Również rozszerzenie prototypów hosta (choć kuszące) jest uważane za zły pomysł .
RobG
Myślę, że powinno to zostać zaktualizowane, aby używać innerTextzamiast innerHTMLunikać luk w zabezpieczeniach skryptów między witrynami. Co myślisz @DavidThomas?
Abhi Beckert
20

Proszę bardzo:

for ( i = 12; i <= 100; i += 1 ) {
    option = document.createElement( 'option' );
    option.value = option.text = i;
    select.add( option );
}

Demo na żywo: http://jsfiddle.net/mwPb5/


Aktualizacja: Ponieważ chcesz ponownie użyć tego kodu, oto odpowiednia funkcja:

function initDropdownList( id, min, max ) {
    var select, i, option;

    select = document.getElementById( id );
    for ( i = min; i <= max; i += 1 ) {
        option = document.createElement( 'option' );
        option.value = option.text = i;
        select.add( option );
    }
}

Stosowanie:

initDropdownList( 'mainSelect', 12, 100 );

Demo na żywo: http://jsfiddle.net/mwPb5/1/

Šime Vidas
źródło
jak zastosować to do więcej niż jednego elementu?
jacktheripper
9

Najbardziej zwięzłym i intuicyjnym sposobem byłoby:

var selectElement = document.getElementById('ageselect');

for (var age = 12; age <= 100; age++) {
  selectElement.add(new Option(age));
}
Your age: <select id="ageselect"><option value="">Please select</option></select>

Możesz także rozróżnić nazwę i wartość lub dodać pozycje na początku listy z dodatkowymi parametrami do używanych funkcji:
HTMLSelect Element .add (item [, before]);
nowa opcja (tekst, wartość, defaultSelected, zaznaczone);

użytkownik
źródło
8

Nie polecam wykonywania manipulacji DOM wewnątrz pętli - może to być kosztowne w przypadku dużych zbiorów danych. Zamiast tego zrobiłbym coś takiego:

var elMainSelect = document.getElementById('mainSelect');

function selectOptionsCreate() {
  var frag = document.createDocumentFragment(),
    elOption;
  for (var i=12; i<101; ++i) {
    elOption = frag.appendChild(document.createElement('option'));
    elOption.text = i;
  }
  elMainSelect.appendChild(frag);
}

Możesz przeczytać więcej o DocumentFragment na MDN , ale oto istota tego:

Jest używany jako lekka wersja dokumentu do przechowywania segmentu struktury dokumentu złożonej z węzłów, tak jak w standardowym dokumencie. Kluczowa różnica polega na tym, że ponieważ fragment dokumentu nie jest częścią faktycznej struktury DOM, zmiany wprowadzone w tym fragmencie nie wpływają na dokument, nie powodują ponownego przepływu ani nie wpływają na wydajność, które mogą wystąpić po wprowadzeniu zmian.

thdoan
źródło
4

Jedyną rzeczą, której bym unikał, jest wykonywanie operacji DOM w pętli, aby uniknąć wielokrotnego renderowania strony.

var firstSelect = document.getElementById('first select elements id'),
    secondSelect = document.getElementById('second select elements id'),
    optionsHTML = [],
    i = 12;

for (; i < 100; i += 1) {
  optionsHTML.push("<option value=\"Age" + i + "\">Age" + i + "</option>";
}

firstSelect.innerHTML = optionsHTML.join('\n');
secondSelect.innerHTML = optionsHTML.join('\n');

Edycja: usunięto funkcję, aby pokazać, jak możesz po prostu przypisać utworzony kod HTML do innego elementu select - w ten sposób unikając niepotrzebnego zapętlenia przez powtarzanie wywołania funkcji.

kinakuta
źródło
jak zastosować to do więcej niż jednego elementu?
jacktheripper
Nie jestem pewien, czy śledzę - chcesz dodać te same opcje do więcej niż jednego wybranego elementu?
kinakuta
Tak, chcę pudełka z tymi samymi opcjami
jacktheripper
Uwzględniłem to w funkcji, którą możesz wywołać, po prostu przekazując identyfikator elementu select, do którego chcesz dołączyć opcje.
kinakuta
2
Do tego służy documentFragment. Możesz łatwo zmodyfikować zaakceptowaną odpowiedź, tak aby opcje były najpierw dołączane do documentFragment, co zapobiega wielokrotnemu renderowaniu.
Sam Braslavskiy,
1

Podczas tworzenia nowego Optionobiektu należy przekazać dwa parametry: pierwszy to tekst, który ma się pojawić na liście, a drugi wartość, która ma być przypisana do opcji.

var myNewOption = new Option("TheText", "TheValue");

Następnie po prostu przypisujesz ten Optionobiekt do pustego elementu tablicy, na przykład:

document.theForm.theSelectObject.options[0] = myNewOption;
mohan mu
źródło
0

Żadne z powyższych rozwiązań nie zadziałało. Metoda dołączania nie dawała błędu, gdy próbowałem, ale nie rozwiązała mojego problemu. W końcu rozwiązałem swój problem z właściwością danych select2. Użyłem json i otrzymałem tablicę, a następnie dałem ją w inicjalizacji elementu select2. Po więcej szczegółów możesz zobaczyć moją odpowiedź w poniższym poście.

https://stackoverflow.com/a/41297283/4928277

Engin Aydogdu
źródło
0

Często masz tablicę powiązanych rekordów, uważam, że wypełnienie w selectten sposób jest łatwe i dość deklaratywne :

selectEl.innerHTML = array.map(c => '<option value="'+c.id+'">'+c.name+'</option>').join('');

Zastąpi to istniejące opcje.
Zamiast tego możesz użyć, selectEl.insertAdjacentHTML('afterbegin', str);aby dodać je do góry.
I selectEl.insertAdjacentHTML('beforeend', str);dodać je na dole listy.

Składnia zgodna z IE11:

array.map(function (c) { return '<option value="'+c.id+'">'+c.name+'</option>'; }).join('');
użytkownik
źródło