jQuery로 select 제어하기

예제 기준 · jQuery : v3.7.1

select를 다루다 보면 선택한 값을 읽는 일 외에도 항목을 추가하거나, 특정 선택지를 막아야 할 때가 있습니다. 자주 쓰는 기능을 jQuery와 순수 JavaScript로 살펴보겠습니다.

예제에는 id="sampleSelect"인 단일 선택 select를 사용합니다. 첫 항목은 빈 값의 ‘선택’이며 Apple, Banana, Orange가 들어 있습니다. 각 코드는 따로 실행하는 예제이며, select 요소가 만들어진 뒤 실행해야 합니다.

선택된 value와 text 읽기

선택한 항목에는 코드에서 사용하는 값과 화면에 보이는 이름이 있습니다. Banana를 선택했다면 value는 banana, text는 Banana입니다.

jQuery

const value = $('#sampleSelect').val();
const text = $('#sampleSelect option:selected').text();

console.log(value, text);

JavaScript

const select = document.querySelector('#sampleSelect');
const value = select.value;
const selected = select.selectedOptions[0];
let text = '';

if (selected) {
    text = selected.text;
}

console.log(value, text);

jQuery에서는 .val(), JavaScript에서는 .value로 값을 읽습니다. 표시 이름은 선택된 option에서 가져옵니다. selectedOptions[0]은 선택 항목이 없으면 undefined이므로 먼저 확인합니다. 여러 항목을 고르는 multiple select는 여기서 다루지 않습니다.

항목을 고르고 ‘현재 값 읽기’를 눌러 보세요.

코드로 select 값 설정하기

Banana를 선택하려면 option의 value인 banana를 지정합니다.

jQuery

const select = $('#sampleSelect');
select.val('banana');

// 초기화가 필요할 때 별도로 실행합니다.
// select.val('');

JavaScript

const select = document.querySelector('#sampleSelect');
select.value = 'banana';

// 초기화가 필요할 때 별도로 실행합니다.
// select.value = '';

빈 문자열을 지정하면 value=""인 ‘선택’ 항목으로 돌아갑니다. 지정한 값에 해당하는 option이 있어야 하며, 값을 설정하는 것만으로 change 이벤트가 발생하지는 않습니다.

아래 버튼으로 Apple이나 Banana를 선택하거나 처음 상태로 되돌릴 수 있습니다.

값 변경과 change 이벤트

사용자가 다른 항목을 선택하면 change 이벤트가 발생합니다. 하지만 .val()로 바꾸면 값만 바뀌고 change에 연결한 코드는 실행되지 않습니다. 그 코드까지 실행하려면 .trigger('change')를 따로 호출해야 합니다.

jQuery

const select = $('#sampleSelect');

select.on('change', function () {
    console.log('change:', select.val());
});

select.val('banana'); // 값만 변경: change 핸들러는 실행되지 않음
select.trigger('change'); // 필요한 경우 명시적으로 실행

JavaScript

const select = document.querySelector('#sampleSelect');

select.addEventListener('change', function () {
    console.log('change:', select.value);
});

select.value = 'banana'; // 이 대입만으로는 change가 발생하지 않음

const event = new Event('change', {
    bubbles: true
});
select.dispatchEvent(event);

select.value에 값을 대입할 때도 마찬가지입니다. dispatchEvent()로 이벤트를 보내고, 부모 요소에서도 받아야 한다면 bubbles: true를 지정합니다. 다만 .trigger('change')가 addEventListener()로 등록한 리스너까지 실행해 주는 것은 아닙니다. 두 방식을 섞어 쓰는 화면에서는 이 차이를 주의해야 합니다.

  • 직접 다른 항목 선택: change 로그가 추가됩니다.
  • .val('banana') 버튼: 선택값과 상태 표시는 바뀌지만 로그는 추가되지 않습니다.
  • 값 설정 후 .trigger('change') 버튼: change 로그가 추가됩니다. 이미 Banana여도 명시적으로 이벤트를 발생시킵니다.

option 동적으로 추가하기

새 option은 new Option(표시 이름, 값)으로 만들 수 있습니다. 같은 값의 항목이 이미 있다면 추가하지 않도록 조건을 넣었습니다.

jQuery

function addTestOption() {
    const existing = $('#sampleSelect option[value="test-1"]');
    if (existing.length > 0) {
        return;
    }

    const option = new Option('Test 1', 'test-1');
    $('#sampleSelect').append(option);
}

addTestOption();

JavaScript

function addTestOption() {
    const select = document.querySelector('#sampleSelect');
    const existing = select.querySelector('option[value="test-1"]');
    if (existing) {
        return;
    }

    const option = new Option('Test 1', 'test-1');
    select.add(option);
}

addTestOption();

만든 option을 jQuery의 .append()나 JavaScript의 .add()로 붙이면 됩니다. JavaScript에서는 select.append(option)도 사용할 수 있습니다.

위 코드는 Test 1 하나를 추가합니다. 아래 실행 예제에서는 버튼을 누를 때마다 Test 1, Test 2처럼 번호를 늘려 여러 항목을 추가할 수 있습니다.

선택된 option 삭제하기

현재 선택한 option을 찾아 삭제합니다. 첫 번째 ‘선택’ 항목은 남겨 두고, 삭제가 끝나면 그 항목으로 돌아가도록 했습니다.

jQuery

function removeSelectedOption() {
    const select = $('#sampleSelect');
    if (select.val() === '' || select.prop('selectedIndex') === 0) {
        return;
    }

    const selected = $('#sampleSelect option:selected');
    if (selected.length === 0) {
        return;
    }

    selected.remove();
    select.prop('selectedIndex', 0);
}

removeSelectedOption();

JavaScript

function removeSelectedOption() {
    const select = document.querySelector('#sampleSelect');
    if (select.value === '' || select.selectedIndex === 0) {
        return;
    }

    const selected = select.selectedOptions[0];
    if (!selected) {
        return;
    }

    selected.remove();
    select.selectedIndex = 0;
}

removeSelectedOption();

selectedIndex는 선택된 항목의 위치이며 첫 항목은 0입니다. 여기서는 첫 항목과 빈 값 항목의 삭제를 막았습니다. 삭제 후 선택을 바꾸는 코드도 change 이벤트를 자동으로 발생시키지는 않습니다.

특정 option 비활성화하기

Orange만 선택할 수 없게 하려면 해당 option의 disabled를 true로 바꿉니다. 이미 Orange가 선택되어 있다면 먼저 ‘선택’ 항목으로 돌려놓습니다.

jQuery

function setOrangeDisabled(disabled) {
    const select = $('#sampleSelect');
    const orange = $('#sampleSelect option[value="orange"]');

    if (disabled === true && orange.prop('selected') === true) {
        select.prop('selectedIndex', 0);
    }
    orange.prop('disabled', disabled);
}

setOrangeDisabled(true);
// 다시 활성화할 때: setOrangeDisabled(false);

JavaScript

function setOrangeDisabled(disabled) {
    const select = document.querySelector('#sampleSelect');
    const orange = select.querySelector('option[value="orange"]');

    if (disabled === true && orange.selected === true) {
        select.selectedIndex = 0;
    }
    orange.disabled = disabled;
}

setOrangeDisabled(true);
// 다시 활성화할 때: setOrangeDisabled(false);

비활성화한다고 기존 선택이 자동으로 해제되지는 않으므로 selected를 확인해 처리했습니다. 다시 선택할 수 있게 하려면 함수에 false를 전달합니다. Orange를 삭제할 수도 있는 화면이라면 option이 남아 있는지도 확인해야 합니다.

select 전체 비활성화하기

select 전체를 잠그려면 select 요소의 disabled를 바꿉니다.

jQuery

const select = $('#sampleSelect');
select.prop('disabled', true);

// 다시 활성화할 때 별도로 실행합니다.
// select.prop('disabled', false);

JavaScript

const select = document.querySelector('#sampleSelect');
select.disabled = true;

// 다시 활성화할 때 별도로 실행합니다.
// select.disabled = false;

두 코드 모두 select를 비활성화하며 현재 선택값은 유지합니다. 다시 사용할 수 있게 하려면 false로 바꾸면 됩니다.

option disabled와 select disabled의 차이

대상 동작
특정 option 그 항목의 사용자 선택을 막습니다. 다른 항목은 선택할 수 있습니다.
select 전체 select의 사용자 조작을 막습니다. 선택값을 자동으로 초기화하지 않습니다.

일부 항목만 막을 때는 option을, 선택 상자 전체를 잠글 때는 select를 비활성화하면 됩니다. 화면에서 선택을 막았더라도 서버에서는 전달받은 값을 별도로 검증해야 합니다.

jQuery와 JavaScript 주요 문법 비교

$select는 jQuery 객체, select는 JavaScript의 DOM 요소를 뜻합니다.

기능 jQuery JavaScript
값 읽기 $select.val() select.value
선택 text option:selected의 .text() selectedOptions[0].text (항목 존재 확인)
값 설정 $select.val('banana') select.value = 'banana'
change 등록 .on('change', handler) .addEventListener('change', handler)
change 발생 .trigger('change') .dispatchEvent(event)
option 추가 $select.append(option) select.add(option)
option 삭제 선택된 jQuery 객체의 .remove() 선택된 DOM 요소의 .remove()
비활성화 .prop('disabled', true) .disabled = true

정리

select를 제어할 때 가장 헷갈리기 쉬운 부분은 값 변경과 change 이벤트입니다. .val()이나 .value로 값을 바꾼 뒤, 연결된 처리도 실행해야 하는지 구분하면 됩니다.

기존 화면이 jQuery를 사용한다면 그 흐름에 맞추고, 순수 JavaScript로 작성하는 화면이라면 표준 DOM API를 사용하면 됩니다.

참고자료