jQuery로 radio 제어하기

예제 기준 · jQuery : v3.7.1

radio는 여러 항목 중 하나를 고를 때 사용합니다. 선택한 값을 읽거나 코드로 선택을 바꿀 때는 value와 checked를 구분하고, change 이벤트가 필요한지도 함께 확인해야 합니다.

과일 항목은 name="fruit"로 묶여 있으며, id와 value는 각각 apple, banana, orange입니다. 각 코드 블록은 따로 실행하며 HTML 요소가 만들어진 뒤 사용합니다. jQuery 코드는 jQuery가 로드된 화면을 기준으로 합니다.

선택된 radio 값 읽기

그룹에서 선택된 항목을 찾으려면 name 조건에 :checked를 붙입니다. 처음에는 아무것도 선택되지 않을 수 있으므로 선택 없음도 처리합니다.

jQuery

const value = $('input[name="fruit"]:checked').val();

if (value === undefined) {
    console.log('선택 없음');
} else {
    console.log(value);
}

JavaScript

const selected = document.querySelector('input[name="fruit"]:checked');

if (selected === null) {
    console.log('선택 없음');
} else {
    console.log(selected.value);
}

Banana를 고르면 banana가 나옵니다. 선택이 없을 때 jQuery의 .val()은 undefined를 반환하고, querySelector()는 null을 반환합니다. null에서 바로 value를 읽으면 오류가 발생합니다.

$('input[name="fruit"]').val()처럼 :checked를 빼면 선택 상태와 관계없이 첫 번째 항목의 값을 읽습니다. value는 항목에 지정한 문자열이고 선택 여부는 checked입니다.

아래에서 아무것도 고르지 않은 상태와 과일을 선택한 상태의 ‘선택값 읽기’ 결과를 비교해 보세요.

특정 radio 선택하기와 선택 초기화

원하는 항목의 checked를 true로 바꾸면 같은 그룹에서 이전에 선택한 항목은 자동으로 해제됩니다. 아래 코드는 value가 banana인 항목을 선택합니다.

jQuery

const banana = $('input[name="fruit"][value="banana"]');
banana.prop('checked', true);

// 선택을 모두 해제할 때 따로 실행합니다.
// $('input[name="fruit"]').prop('checked', false);

JavaScript

const banana = document.querySelector('input[name="fruit"][value="banana"]');
banana.checked = true;

// 선택을 모두 해제할 때 호출합니다.
function clearSelection() {
    const fruits = document.querySelectorAll('input[name="fruit"]');
    for (let i = 0; i < fruits.length; i++) {
        fruits[i].checked = false;
    }
}
// clearSelection();

현재 선택 상태에는 .prop('checked', ...) 또는 checked 프로퍼티를 사용합니다. HTML의 checked 속성은 기본 선택 상태를 지정하는 용도입니다. banana.value = 'banana'처럼 value를 대입하는 것은 선택 동작이 아닙니다.

선택된 radio를 다시 클릭해도 선택은 해제되지 않습니다. 모두 해제하려면 그룹의 checked를 false로 설정합니다. 여기서 ‘선택 초기화’는 모두 해제를 뜻하며, HTML의 기본 선택 상태로 되돌리는 form.reset()과는 다릅니다.

아래의 ‘Apple 선택’, ‘Banana 선택’, ‘선택 초기화’ 버튼은 change를 발생시키지 않고 선택 상태와 결과 표시를 직접 갱신합니다.

radio 선택 여부 확인하기

Apple이 선택됐는지 확인할 때는 .is(':checked')로 true 또는 false를 얻습니다. 그룹에 선택된 항목이 있는지는 :checked로 찾은 개수로 확인할 수 있습니다.

jQuery

const appleChecked = $('#apple').is(':checked');
const selected = $('input[name="fruit"]:checked');

console.log('Apple 선택:', appleChecked);
console.log('그룹 선택 있음:', selected.length > 0);

JavaScript

const apple = document.querySelector('#apple');
const selected = document.querySelector('input[name="fruit"]:checked');

console.log('Apple 선택:', apple.checked);
console.log('그룹 선택 있음:', selected !== null);

:checked는 선택된 요소를 찾는 조건이고, .is(':checked')는 해당 조건에 맞는 요소가 있는지 확인하는 메서드입니다. 문법은 .is(':checked')이며 :is(':checked')가 아닙니다. 여러 radio에 .is(':checked')를 호출하면 그중 하나라도 선택됐을 때 true가 됩니다.

아래의 ‘선택 여부 확인’ 버튼은 Apple의 선택 여부와 현재 과일 선택값을 함께 표시합니다. Banana를 고르면 Apple은 false지만 그룹에는 선택값이 있습니다.

checked 변경과 change 이벤트

사용자가 다른 radio를 선택하면 새로 선택된 항목에서 change 이벤트가 발생합니다. 같은 그룹에서 자동으로 해제된 항목에는 change가 발생하지 않으며, 이미 선택된 항목을 다시 클릭해도 선택은 바뀌지 않습니다.

jQuery

const fruits = $('input[name="fruit"]');
const apple = $('#apple');

fruits.on('change', function (event) {
    console.log('change:', $(event.target).val());
});

$('#valueOnly').on('click', function () {
    apple.prop('checked', true);
});

$('#valueAndChange').on('click', function () {
    apple.prop('checked', true);
    apple.trigger('change');
});

JavaScript

const fruits = document.querySelectorAll('input[name="fruit"]');
const apple = document.querySelector('#apple');

for (let i = 0; i < fruits.length; i++) {
    fruits[i].addEventListener('change', function (event) {
        console.log('change:', event.target.value);
    });
}

document.querySelector('#valueOnly').addEventListener('click', function () {
    apple.checked = true;
});

document.querySelector('#valueAndChange').addEventListener('click', function () {
    apple.checked = true;
    const event = new Event('change', { bubbles: true });
    apple.dispatchEvent(event);
});

.prop('checked', true)와 apple.checked = true는 상태만 바꾸며 change를 발생시키지 않습니다. 이벤트에 연결한 처리도 필요하면 별도로 호출해야 합니다. 위 코드는 두 버튼의 핵심 동작이며, 아래 예제에서는 결과 표시와 화면 로그도 함께 갱신합니다.

  • 다른 과일을 직접 선택하면 새로 선택된 항목의 change 로그가 추가됩니다.
  • prop만 실행하는 버튼은 Apple 선택과 결과 표시만 바꾸고 로그는 추가하지 않습니다.
  • trigger까지 실행하는 버튼은 Apple이 이미 선택돼 있어도 누를 때마다 로그를 추가합니다.

bubbles: true는 이벤트가 부모 요소로 전파되도록 합니다. jQuery의 .trigger('change')는 addEventListener()로 등록한 change 리스너를 호출하지 않습니다. 네이티브 리스너에도 전달하려면 dispatchEvent()를 사용합니다. 이벤트를 보내는 것 자체가 checked를 바꾸지는 않으므로 상태를 먼저 설정합니다.

‘로그 지우기’는 기록만 지우고 선택은 유지합니다.

특정 radio 비활성화와 활성화

Apple을 사용자가 직접 선택하지 못하게 하려면 disabled를 true로 설정합니다. false로 바꾸면 다시 선택할 수 있습니다.

jQuery

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

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

JavaScript

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

// 다시 활성화할 때 따로 실행합니다.
// apple.disabled = false;

비활성화만으로 선택이 해제되지는 않습니다. Apple을 선택한 뒤 비활성화하면 checked는 그대로 true입니다. 다만 활성화된 Banana를 선택하면 같은 그룹의 Apple은 해제됩니다. 특정 항목의 disabled는 그룹 전체의 선택을 고정하는 기능이 아닙니다.

disabled 상태여도 코드로 checked를 바꿀 수 있고, :checked로 값을 읽을 수 있습니다. 단, 비활성화된 항목은 일반적인 폼 제출 데이터에 포함되지 않으므로 화면에서 읽은 선택값과 제출값은 구분해야 합니다.

radio group 동작

같은 그룹에서는 최대 하나만 선택할 수 있습니다. 예제의 과일은 name="fruit", 음료는 name="drink"이므로 서로 독립적입니다. 음료의 id와 value는 water, tea, coffee입니다.

jQuery

function readGroupValue(name) {
    const value = $('input[name="' + name + '"]:checked').val();
    if (value === undefined) {
        return '선택 없음';
    }
    return value;
}

function showGroupValues() {
    console.log('fruit:', readGroupValue('fruit'));
    console.log('drink:', readGroupValue('drink'));
}

$('input[type="radio"]').on('change', showGroupValues);
showGroupValues();

JavaScript

function readGroupValue(name) {
    const selected = document.querySelector('input[name="' + name + '"]:checked');
    if (selected === null) {
        return '선택 없음';
    }
    return selected.value;
}

function showGroupValues() {
    console.log('fruit:', readGroupValue('fruit'));
    console.log('drink:', readGroupValue('drink'));
}

const radios = document.querySelectorAll('input[type="radio"]');
for (let i = 0; i < radios.length; i++) {
    radios[i].addEventListener('change', showGroupValues);
}
showGroupValues();

Apple과 Tea를 선택한 뒤 과일을 Banana로 바꿔도 Tea는 유지됩니다. 위 함수의 name에는 예제에서 정한 fruit와 drink만 전달합니다. 아래 예제는 각 그룹의 값과 선택 개수를 화면에 표시하며, 선택할 때마다 갱신합니다.

그룹은 name뿐 아니라 같은 폼에 속하는지도 영향을 받습니다. 같은 문서에서 폼에 속하지 않은 radio끼리 또는 같은 폼에 속한 radio끼리 같은 name을 쓰면 하나의 그룹이 됩니다. 서로 다른 폼에 같은 name이 있다면 값을 읽을 때도 해당 폼 안으로 검색 범위를 좁혀야 합니다. fieldset을 나누는 것만으로 같은 name의 그룹이 분리되지는 않습니다.

jQuery와 JavaScript 주요 문법 비교

아래의 $radio는 jQuery 객체, radio는 radio DOM 요소입니다. 값 읽기는 먼저 :checked로 선택된 항목을 찾고, 선택이 없는 경우를 처리한 뒤 사용합니다.

기능 jQuery JavaScript
값 읽기 $radio.val() radio.value
선택 여부 $radio.is(':checked') radio.checked
선택 설정 $radio.prop('checked', true) radio.checked = true
선택 해제 $radio.prop('checked', false) radio.checked = false
비활성화 $radio.prop('disabled', true) radio.disabled = true
활성화 $radio.prop('disabled', false) radio.disabled = false
change 발생 $radio.trigger('change') radio.dispatchEvent(new Event('change', { bubbles: true }))

radio는 그룹별로 선택된 항목을 찾고, value·checked·disabled를 각각의 목적에 맞게 다루면 됩니다. 코드로 선택을 바꾼 뒤에는 화면을 직접 갱신할지, change에 연결된 처리를 실행할지 결정하면 됩니다.

참고자료