관련 지식
#javascript #jquery #radio-button

이용약관 등에서 ‘동의’ 항목이 선택되어 있는지 확인이 필요한 경우가 있습니다. 보통 여러개의 라디오 버튼이 존재하는데 아이디로 확인하려고 하기엔 너무 많은 아이디를 지정해야 합니다. 그리고 특별한 동작은 없이 ‘동의’ 선택 여부만 확인한다면 좀더 편한 방법이 있을것 같습니다. 따라서 JQuery로 단순 체크 유무 판단을 쉽게하는 방법을 설명 드리겠습니다.

위와 같은 화면에서 버튼을 클릭했을때 모든 항목이 ‘동의함’ 인지 체크하고 ‘동의 안함’ 이 있을 경우 alert() 과 함께 포커스를 이동하고 싶습니다.

HTML 샘플은 아래와 같습니다.

  1. <div>
  2. <input type="radio" name="grp1" value="Y"/> 동의함
  3. <input type="radio" name="grp1" value="N" checked="checked"/> 동의 안함
  4. </div>
  5. <div>
  6. <input type="radio" name="grp2" value="Y"/> 동의함
  7. <input type="radio" name="grp2" value="N" checked="checked"/> 동의 안함
  8. </div>
  9. <div>
  10. <input type="radio" name="grp3" value="Y"/> 동의함
  11. <input type="radio" name="grp3" value="N" checked="checked"/> 동의 안함
  12. </div>
  13. <div>
  14. <input type="radio" name="grp4" value="Y"/> 동의함
  15. <input type="radio" name="grp4" value="N" checked="checked"/> 동의 안함
  16. </div>
  17. <div>
  18. <input type="radio" name="grp5" value="Y"/> 동의함
  19. <input type="radio" name="grp5" value="N" checked="checked"/> 동의 안함
  20. </div>
  21. <div>
  22. <input type="radio" name="grp6" value="Y"/> 동의함
  23. <input type="radio" name="grp6" value="N" checked="checked"/> 동의 안함
  24. </div>
  25. <div>
  26. <input type="radio" name="grp7" value="Y"/> 동의함
  27. <input type="radio" name="grp7" value="N" checked="checked"/> 동의 안함
  28. </div>

이렇게 하지 말것

위에서 정의한 규칙이라면 매우 단순 반복적이고 예외가 없습니다. 절대로 아래처럼 만들지 마세요.

  1. $("#btn").on("click", function() {
  2. if(!$("#아이디1").is(":checked")) {
  3. alert("반드시 동의해야 합니다.").
  4. $("#아이디1").focus();
  5. return;
  6. }
  7. ... 반복 ...
  8. });

위와 같은 코딩은 불필요하게 아이디를 지정해야 하고 소스가 길어집니다. 또한 아이디를 찾기위해 JQuery의 반복적인 DOM 탐색으로 효율도 좋지 않습니다.

라디오 버튼 선택 확인 방법

  1. 라디오 버튼의 위치를 이용한 방법
    조금 복잡해 보이지만 하나씩 보면 간단하니다. ‘동의함’과 ‘동의안함’ 버튼이 규칙적으로 나열되어 있으므로 홀수번째 라디오 버튼만 가져와 선택 여부를 확인 후 포커스를 주는 것입니다. for 구문 대신 JQuery의 each() 함수를 사용하게 될 경우 return으로 반복실행을 멈출수 없으므로 주의 바랍니다.

    1. $("#btn").on("click", function() {
    2. var radios = $(":radio:nth-child(odd)");
    3. for(var i = 0; i < radios.length; i++) {
    4. var $this = $(radios[i]);
    5. if(!$this.is(":checked")) { //동의함이 선택되어있지 않다면
    6. alert('반드시 동의해야 합니다.');
    7. $this.focus();
    8. return;
    9. }
    10. }
    11. });
  2. 버튼의 값을 이용한 방법
    보통 특별한 일이 없을 경우 라디오 버튼의 값을 매우 단순하게 ‘1/0’ 아니면 ‘Y/N’ 또는 ‘true/false’ 등으로 반복될 것입니다. 그러한 상황에선 아래처럼 체크할 수 있습니다.

    1. $("#btn").on("click", function() {
    2. var radios = $(":radio[value='Y']");
    3. for(var i = 0; i < radios.length; i++) {
    4. var $this = $(radios[i]);
    5. if(!$this.is(":checked")) { //동의함에 선택되어있지 않다면
    6. alert('반드시 동의해야 합니다.');
    7. $this.focus();
    8. return;
    9. }
    10. }
    11. });

    루프 부분은 완전히 동일하고 선택자만 바뀌었습니다. 이전과 다르게 값이 ‘Y’ 인 항목의 라디오 버튼만 가져와서 체크가 되어있는지 확인하고 있습니다. 만약 체크해야 할 항목의 값이 ‘true’ 라면 해당 선택자의 조건만 바꿔주면 되겠습니다.

  3. 순서도 불규칙하고 라디오 버튼의 값도 완전히 다른 경우
    순서가 불규칙한 경우는 없겠지만 라디오 버튼에 들어가는 값이 달라야할 경우는 있을 것입니다. 그렇더라도 단순 반복 작업이란 것은 달라지지 않습니다. 아래 HTML은 처음 보였던 HTML 부분의 일부 입니다. 그런데 value 속성의 값이 제각각이란걸 보실수 있습니다. 순서도 불규칙적입니다.

    1. <div>
    2. <input type="radio" name="grp1" data-agree="Y" value="true"/> 동의함
    3. <input type="radio" name="grp1" data-agree="N" value="N" checked="checked"/> 동의 안함
    4. </div>
    5. <div>
    6. <input type="radio" name="grp2" data-agree="N" value="no" checked="checked"/> 동의 안함
    7. <input type="radio" name="grp2" data-agree="Y" value="1"/> 동의함
    8. </div>
    9. ...

    그래서 data-agree라는 속성을 추가하였습니다. 선택자에서 data-agree 속성을 참조하면 ‘동의함’ 을 체크하거나 ‘동의 안함’을 일괄 체크하는데 어렵지 않으실 겁니다. 2번과 크게 다를게 없는 예라 샘플은 생략합니다.

정리

어떠한 상황에서도 반복적인 코드를 만드는것은 유지보수에 좋지 않습니다. 일관된 규칙을 가진 반복적인 코드는 정리하는 방법을 찾아보는 것이 좋습니다.

최종 샘플

주석 풀고 테스트 하세요

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  8. <title>Document</title>
  9. </head>
  10. <body>
  11. <div class="wrap">
  12. <div>
  13. <input type="radio" name="grp1" value="Y"/> 동의함
  14. <input type="radio" name="grp1" value="N" checked="checked"/> 동의 안함
  15. </div>
  16. <div>
  17. <input type="radio" name="grp2" value="Y"/> 동의함
  18. <input type="radio" name="grp2" value="N" checked="checked"/> 동의 안함
  19. </div>
  20. <div>
  21. <input type="radio" name="grp3" value="Y"/> 동의함
  22. <input type="radio" name="grp3" value="N" checked="checked"/> 동의 안함
  23. </div>
  24. <div>
  25. <input type="radio" name="grp4" value="Y"/> 동의함
  26. <input type="radio" name="grp4" value="N" checked="checked"/> 동의 안함
  27. </div>
  28. <div>
  29. <input type="radio" name="grp5" value="Y"/> 동의함
  30. <input type="radio" name="grp5" value="N" checked="checked"/> 동의 안함
  31. </div>
  32. <div>
  33. <input type="radio" name="grp6" value="Y"/> 동의함
  34. <input type="radio" name="grp6" value="N" checked="checked"/> 동의 안함
  35. </div>
  36. <div>
  37. <input type="radio" name="grp7" value="Y"/> 동의함
  38. <input type="radio" name="grp7" value="N" checked="checked"/> 동의 안함
  39. </div>
  40. <input type="button" id="btn" value="선택여부 확인"/>
  41. </div>
  42. <script>
  43. // 절대 이렇게 만들지 말것
  44. /*
  45. $("#btn").on("click", function() {
  46. if(!$("#아이디1").is(":checked")) {
  47. alert("반드시 동의해야 합니다.").
  48. $("#아이디1").focus();
  49. return;
  50. }
  51. });
  52. */
  53. // 라디오 버튼의 위치를 이용한 방법
  54. /*
  55. $("#btn").on("click", function() {
  56. var radios = $(":radio:nth-child(odd)");
  57. for(var i = 0; i < radios.length; i++) {
  58. var $this = $(radios[i]);
  59. if(!$this.is(":checked")) { //동의함에 선택되어있지 않다면
  60. alert('반드시 동의해야 합니다.');
  61. $this.focus();
  62. return;
  63. }
  64. }
  65. });
  66. */
  67. // 버튼의 값을 이용한 방법
  68. /*
  69. $("#btn").on("click", function() {
  70. var radios = $(":radio[value='Y']");
  71. for(var i = 0; i < radios.length; i++) {
  72. var $this = $(radios[i]);
  73. if(!$this.is(":checked")) { //동의함에 선택되어있지 않다면
  74. alert('반드시 동의해야 합니다.');
  75. $this.focus();
  76. return;
  77. }
  78. }
  79. });
  80. */
  81. </script>
  82. </body>
  83. </html>