🧑‍💻개발/jQuery

[jQuery]FE 필수 기술인, Select 창을 원하는대로 만들 수 있는 방법

무택 2024. 3. 13.

 

안녕하세요 무택입니다 :)

오늘은 Select창을 원하는 대로 만드는 방법에 대해 알아보도록 하겠습니다. Select창은 쓰이는 곳이 정말 많습니다. 간단한 페이지라면 사용하지 않을 수 있지만 어느 정도 규모가 있는 곳이라면 당연히 Select창을 쓰게 되겠죠.

 

하지만 이 Select창을 그냥 기본 디자인으로 사용하는 건 디자이너로써 지켜볼 수가 없습니다..😠

그래서 오늘은 이 Select form을 어떻게 이쁘게, 원하는 대로 만들 수 있는지 알아보도록 할게요!

 

 

Select 창을 원하는대로 만들 수 있는 방법

Select창 원하는대로 만들기 이미지

 

 

HTML/CSS

<style>
*{ list-style : none; padding: 0; margin: 0;}

.custom_select_con {
  position: relative;
  width: 100%
}

.custom_select_con .slt_custom {
  border: 2px solid #b3b3b3;
  background-color: #fff;
  height: 34px;
  padding: 0 12px 0 8px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
}

.custom_select_con .slt_custom:hover {
  cursor: pointer;
}

.custom_select_con .slt_custom>span {
  font-size: 13px;
  color: #4c4c4c;

  font-weight: bold;
}

.custom_select_con .slt_custom>span>span {
  font-weight: normal;
}

.custom_select_con .slt_custom .arrow {
  position: relative;
}

.custom_select_con .slt_custom .arrow::after {
  content: '';
  display: inline-block;
  margin-right: 2px;
  width: 5px;
  height: 5px;
  background-color: #fff;
  position: relative;
  top: -4px;
  transform: rotate(45deg);
  border: solid 2px #000;
  border-top: none;
  border-left: none;
}

.custom_select_con .slt_ul {
  border: 2px solid #b3b3b3;
  background-color: #fff;
  width: 100%;
  max-height: 240px;
  overflow-y: auto;
  position: absolute;
  z-index: 1;
  left: 0;
  border-top: none;
}

.custom_select_con .slt_ul li {
  font-size: 13px;
  color: #4c4c4c;
  padding: 0 12px 0 8px;
  font-weight: bold;
  border-bottom: 1px solid #f2f2f2;
  line-height: 34px;
}

.custom_select_con .slt_ul li:first-child {
  border-top: 1px solid #f2f2f2;
}

.custom_select_con .slt_ul li:last-child {
  border-bottom: none;
}

.custom_select_con .slt_ul li:hover {
  background-color: #f6f8fd;
  color: #6a8fed;
  cursor: pointer;
}

.custom_select_con .slt_ul li span {
  font-weight: normal;
}

.custom_select_con .slt_org  {
  font-weight: bold;
}
</style>
<div class="custom_select_con">
  <div class="slt_custom">
    <span class="slt_txt">옵션1<span> 세부정보</span></span>
    <div class="arrow"></div>
  </div>
  <ul class="slt_ul" style="display:none;">
    <li data-value="option1" class="slt_option">옵션1<span> 세부정보</span>
    </li>
    <li data-value="option2" class="slt_option">옵션2<span> 세부정보</span>
    </li>
    <li data-value="option3" class="slt_option">옵션3<span> 세부정보</span>
    </li>
  </ul>

  <select id="slt_org" style="display: ;">
    <option value="option1" selected="selected">옵션1<span>세부정보</span></option>
    <option value="option2">옵션2<span>세부정보</span></option>
    <option value="option3">옵션3<span>세부정보</span></option>
  </select>
</div>

 

 

jQuery

$(document).on('click', function(event) {
  console.log($(event.target).closest('.custom_select_con').length)
  if (!$(event.target).closest('.custom_select_con').length) {
    $('.slt_ul').hide();
  }
});

$('.slt_custom').on('click', function () {
  $('.slt_ul').toggle();
});

$('.slt_option').on('click', function () {
  let value = $(this).attr('data-value');
  let text = $(this).html();

  $('.slt_txt').html(text);
  $('.slt_ul').hide();

  $('#slt_org').find('option').each(function (index, el) {
    if ($(el).attr('value') == value) {
      $(el).attr('selected', 'selected');
    } else {
      $(el).removeAttr('selected');
    }
  });
});

 

 

Codepen

See the Pen [jQuery]Select 창 커스텀 하기 by TytanLee (@TytanLee) on CodePen.

 

 

코드 원리

1. 기본 셀렉트 창은 숨겨준다.

2. 커스텀한 셀렉트 창을 보여준다.

3. 커스텀 셀렉트 창을 클릭하면 옵션을 보여주고, 옵션을 선택하면 커스텀 셀렉트 창에 반영해 준다.

4. 커스텀 셀렉트 창에서 선택한 옵션을 기본 셀렉트 value에도 반영해 준다.

 

 

코드 설명

// 다른 곳 클릭 시 select창 사라지기
$(document).on('click', function(event) {
  console.log($(event.target).closest('.custom_select_con').length)
  if (!$(event.target).closest('.custom_select_con').length) {
    $('.slt_ul').hide();
  }
});

 

위 코드는 'Select 창이 아닌, 다른 곳 클릭 시 Select창 사라지기' 기능입니다.

 

`$(event.target).closest('.custom_select_con').length`코드는 클릭한 곳의 조상 중에 괄호 안의 코드(.custom_select_con)가 있는지 찾습니다.

 

즉 `.custom_select_con` 내부 요소를 클릭했냐, 안 했냐를 따지는 겁니다. 내부요소를 클릭하면 `length`가 0보다 커지게 됩니다. 반대로 바깥을 클릭하면 `length`가 0이 됩니다. 조상 중에 괄호 안의 코드가 없기 때문이죠.

 

우리는 바깥을 클릭했을 때 ul을 숨겨줘야 하기 때문에 바깥을 클릭했을 경우를 if()조건 안에 넣어야 합니다.
바깥을 클릭했을 때는 0(false)가 나오는데 if 조건 안에는 true가 들어가야 하기 때문에 !를 붙여서 조건을 만들어줍니다.

 

 

// 커스텀한 ul을 보여주는 기능
$('.slt_custom').on('click', function () {
  $('.slt_ul').toggle();
});

// 커스텀 ul에서 옵션을 선택하면 select에 적용하는 기능
$('.slt_option').on('click', function () {
  let value = $(this).attr('data-value');
//   attr은 html에서 요소의 속성을 가져오거나 변경하는 함수.
  let text = $(this).html();

  $('.slt_txt').html(text);
  $('.slt_ul').hide();

  // 옵션을 선택하면 기본 select에도 적용시키는 기능
  $('#slt_org').find('option').each(function (index, el) {
    if ($(el).attr('value') == value) {
      $(el).attr('selected', 'selected');
//       el의 selected 속성을 selected 값으로 변경.
    } else {
      $(el).removeAttr('selected');
    }
  });
});

 

커스텀 Select 코드는 더 쉽습니다.

우선 커스텀 Select에 `data-value` 값을 넣어줘야 합니다.

<li data-value="option1" class="slt_option">옵션1<span> 세부정보</span></li>

 

위 부분에서 "option1"이라고 지정한 것처럼 말이죠. 

그래서 위 값이랑 선택한 옵션의 html을 그대로 가져와서 변수로 저장해 줍니다.`(let value, let text)`

그리고 커스텀한 셀렉트 창에서 선택한 옵션이 보여지는 부분`(.slt_txt)`에 변수를 넣습니다.

 

그리고 또 해줘야 할 게 있죠. 기본 셀렉트 창에도 옵션을 반영해 줘야 합니다.

기본 셀렉트의 옵션들을 배열로 만들어서 커스텀 셀렉트에서 선택한 옵션과 똑같은 게 있는지 찾아줍니다. 같은 옵션을 찾는다면 그 옵션의 `selected` 값을 ` selected`로 넣어주면 그 옵션이 선택된 것과 똑같이 됩니다.

 

 

최대한 쉽게 설명하려고 했는데 잘 이해가 될지 모르겠습니다😥

어려운 부분이 있다면 댓글로 남겨주세요!