관련지식
javascript, jquery

이전 글에서 라디오 버튼을 컨트롤 하는 방법을 적어봤습니다. 이번엔 체크박스를 컨트롤 하는 내용을 다뤄보겠습니다.

자신이 좋아하는 음식을 고르게 하는 화면을 만들 경우 어떻게 HTML을 만드시나요?

이름과 값을 지정하는 형태

  1. <input type="checkbox" name="test1" value="AA"/> 삼겹살
  2. <input type="checkbox" name="test2" value="BB" /> 치킨
  3. <input type="checkbox" name="test3" value="CC" /> 족발

HTML 폼에서 가장 일반적인 형태입니다. 그러나 체크가 안된 항목의 값은 파라미터로 전달되지 않기 때문에 값 자체가 크게 의미가 없습니다.

이름만 지정하는 형태

  1. <input type="checkbox" name="test1"/> 삼겹살
  2. <input type="checkbox" name="test2"/> 치킨
  3. <input type="checkbox" name="test3"/> 족발

이 형태도 많이 사용합니다. value 값이 없어도 체크된 항목의 파라미터는 on이라는 값으로 전달되기 때문입니다.

ID만 지정하기

  1. <input type="checkbox" id="test1"/> 삼겹살
  2. <input type="checkbox" id="test2"/> 치킨
  3. <input type="checkbox" id="test3"/> 족발

ID만 지정하고 입력폼 검증 단계에서 체크 유/무를 확인, 그 결과를 다른 파라미터로 가공할수도 있습니다.

추천

그런데 삼겹살, 치킨, 족발은 각각 개별 컨트롤이지만 같은 속성(좋아하는 음식 종류) 이기도 합니다. 이러한 경우 앞으로는 아래처럼 만드는것을 추천합니다.

  1. <input type="checkbox" name="favorite" value="AA"/> 삼겹살
  2. <input type="checkbox" name="favorite" value="BB"/> 치킨
  3. <input type="checkbox" name="favorite" value="CC"/> 족발

마치 라디오 버튼과 비슷한 형태가 되었습니다. 그런데 이것은 큰 장점이 있습니다.

  1. 많은 ID가 필요 없음
  2. 많은 이름이 필요 없음
  3. 데이터를 조회하여 checked 속성을 부여할때 유리함

만약 화면이 열리면서 내가 좋아하는 음식을 조회했을때 값이 BB, CC였다면 아래와 같으 변수가 만들어질 것입니다.

  1. var checkboxVal = ['BB', 'CC'];

이 값으로 checked 속성을 부여할때 아래와 같이 할수 있습니다.

  1. $.fn.checkboxSelect = function(val) {
  2. if(!Array.isArray(val))
  3. val = [val];
  4. this.each(function() {
  5. var $this = $(this);
  6. var map = val.reduce(function(accu, v) {
  7. accu[v] = true;
  8. return accu;
  9. }, []);
  10. map[$this.val()] ? $this.attr('checked', true) : $this.attr('checked', false);
  11. });
  12. return this;
  13. };
  14. $(":checkbox[name='favorite']").checkboxSelect(checkboxVal);

조회한 값과 일치하는 항목은 체크되고 일치하지 않는 항목은 체크해제 됩니다.
같은 속성을 가진 여러개의 체크박스를 컨트롤하기 위해 불필요한 많은 코딩을 요구하지 않죠.

단일 값을 지정할수도 있습니다.

  1. $(":checkbox[name='favorite']").checkboxSelect("AA");

만약 체크여부 값이 여러개의 변수로 있어도 단순하게 처리할수 있습니다.

  1. var val1 = 'AA', val2 = 'CC';
  2. $(":checkbox[name='favorite']").checkboxSelect([val1, val2]);

단, 위 코드는 reduce()를 사용했기 때문에 하위 브라우저에선 polyfill을 적용하거나, 해당 코드를 바꾸셔야 합니다.

하위 호환 코드)

  1. var map = [];
  2. for(var i = 0; i < val.length; i++) {
  3. map[val[i]] = true;
  4. }

최종샘플

  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">
  6. <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  7. <style>
  8. .group { border:1px solid gray; }
  9. </style>
  10. </head>
  11. <body>
  12. <input type="button" id="btn1" value='POST 송신'/>
  13. <form id="frm1" method="post">
  14. <input type="checkbox" name="test1" /> 삼겹살
  15. <input type="checkbox" name="test2" checked/> 치킨
  16. <input type="checkbox" name="test3" /> 족발
  17. </form>
  18. <input type="button" id="btn2" value='동일한 이름으로 POST 송신'/>
  19. <form id="frm2" method="post">
  20. <input type="checkbox" name="test" value="AA"/> 삼겹살
  21. <input type="checkbox" name="test" value="BB" checked/> 치킨
  22. <input type="checkbox" name="test" value="CC" checked/> 족발
  23. </form>
  24. <div class="group">
  25. <pre>
  26. $.fn.checkboxSelect = function(val) {
  27. if(!Array.isArray(val))
  28. val = [val];
  29. this.each(function() {
  30. var $this = $(this);
  31. var map = val.reduce(function(accu, v) {
  32. accu[v] = true;
  33. return accu;
  34. }, []);
  35. map[$this.val()] && $this.attr('checked', true);
  36. });
  37. return this;
  38. };
  39. </pre>
  40. <input type="checkbox" name="favorite" value="AA"/> 삼겹살
  41. <input type="checkbox" name="favorite" value="BB"/> 치킨
  42. <input type="checkbox" name="favorite" value="CC"/> 족발
  43. </div>
  44. <script>
  45. $("#btn1").on('click', function() {
  46. $('#frm1').attr('src', '/asdfasdf').submit(); //URL은 뭐가 되도 상관없음. 개발자도구 확인용
  47. });
  48. $("#btn2").on('click', function() {
  49. $('#frm2').attr('src', '/asdfasdf').submit(); //URL은 뭐가 되도 상관없음. 개발자도구 확인용
  50. });
  51. $.fn.checkboxSelect = function(val) {
  52. if(!Array.isArray(val))
  53. val = [val];
  54. this.each(function() {
  55. var $this = $(this);
  56. var map = val.reduce(function(accu, v) {
  57. accu[v] = true;
  58. return accu;
  59. }, []);
  60. map[$this.val()] ? $this.attr('checked', true) : $this.attr('checked', false);
  61. });
  62. return this;
  63. };
  64. var checkboxVal = ['BB', 'CC'];
  65. $(":checkbox[name='favorite']").checkboxSelect(checkboxVal);
  66. // $(":checkbox[name='favorite']").checkboxSelect("AA");
  67. </script>
  68. </body>
  69. </html>