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를 사용하면 됩니다.
