create account

[Python #19] [Django #12] 검색 기능 UI 다듬기 by june0620

View this thread on: hive.blogpeakd.comecency.com
· @june0620 · (edited)
$2.16
[Python #19] [Django #12] 검색 기능 UI 다듬기
pixabay
https://cdn.pixabay.com/photo/2019/03/12/20/27/kanban-4051777_1280.jpg
***

검색 기능 UI를 좀 더 다듬어 본다. HTML form을 그대로 사용했고 CSS 가 없다 보니 영 보기 안 좋다. 

#### 구상
1. 큰 검색 박스 하나를 메인에 두고, 구현된 세 개 기능(태그 검색, 타이틀 검색, 내용 검색) 중 내용 검색만 노출
2. 복수 키워드를 받을 수 있어야 하므로, 여러 개를 받을 수 있는 기능 구현
3. [상세 검색] 버튼 하나 추가, 클릭 시 태그 검색, 타이틀 검색, 내용 검색 세 가지 노출

더 상세하게 만들고 싶지만 시간이 많이 들 것 같아 일단 이 정도로 구현한다. 게다가 CSS, JS는 초짜라 어떻게 내 힘으로 할 수가 없어 더 많은 기능은 욕심이다. 이 정도도 오픈소스의 힘을 빌려 본다.

###### 소스 탐색1
인터넷에서 검색 박스 마크업을 검색해 보니 역시 Bootstrap 예제가 많이 나온다. 
https://colorlib.com/wp/free-css3-html5-search-form-examples/ 에서 가장 마음에 드는 v4를 사용하자. 복수 키워드 검색까지 구현돼 있어 1, 2번은 한 번에 해결될 것 같다. (#다운로드고고#오픈소스감사)
![](https://cdn.steemitimages.com/DQmQukh3k1T2ungVeFwqvT1WecURkGGVmkzZQdsbFwpZGAn/image.png)

###### 소스 탐색2
3번은 w3schools에 예제가 있다. 필요한 코드만 가져가면 될 거 같다. 
https://www.w3schools.com/howto/howto_js_collapsible.asp

그런데 한 가지 문제가 있다. 이 두 개 코드를 합치는 방법을 잘 모르겠다. 메인 검색 박스 우측에 작은 버튼 하나 만들고, 누르면 아래로 상세 메뉴가 노출되게 하는 게 목적인데... ㅎㅎㅎ 그건 차차 배우면서 하고 일단 순서대로 노출 시켜본다. 배경색 정도는 직접 추가하자. 내가 좋아하는 파랑, 초록, 노랑, 빨강 단색으로...

#### 구현
우선 프로젝트 root에 static 폴더 하나를 만들고 하위에 css, images, js 폴더를 만들어 위에서 다운로드 한 파일을 각각 위치에 맞게 넣는다. 
![](https://cdn.steemitimages.com/DQmYci2Cf1M6XyaQqz53rkkSSKWttad9merFysHdES5BgMY/image.png)

다음은 장고에서 지원하는 방법으로 static 폴더를 읽어오도록 settings.py에서 static 파일 경로를 지정해 준다. 
```
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/

STATIC_URL = '/static/'

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]
```
<p></p>

![](https://cdn.steemitimages.com/DQmdgHuxTVzcrmJGBUz4hCHzBXBZZMn1Hjdo9uzhv8PxTpL/image.png)


검색 기능은 메인에 노출해야 하므로 base.html에 코드를 추가하자. 주의할 점은 `{% load static %}`로 static 파일을 읽어야 한다. 또한 `<link href="{% static 'css/main.css' %}" rel="stylesheet" />`로 css 파일을 읽어온다. 

```
{% load static %}
{% load post_extras %}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css?family=Poppins:400,800" rel="stylesheet" />
<link href="{% static 'css/main.css' %}" rel="stylesheet" />

{% spaceless %}
{% endspaceless %}

<html lang="en">
  <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
      <title>D_Blog</title>
      
  </head>
  <body>
      <header>
          <nav>
              <div class="s004">
              <form action="/{{ request.path | get_account_form_url }}/search/" method="get">
                  <div class="inner-form">
                    <div class="input-field">
                      <input class="form-control" id="choices-text-preset-values" name="texts" type="text" placeholder="Type to search..." />
                        <button class="btn-search" type="submit">
                            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
                          <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
                            </svg>
                        </button>
                      </div>
                  </div>
              </form>
              </div>
              <div class="collapsible-container">
                  <button class="collapsible">Advanced search</button>
                  <div class="content">
                      <form class="adv-form" action="/{{ request.path | get_account_form_url }}/search/" method="get">
                          <input id="tags" type="text" name="tags" value="" placeholder="tags">
                          <input id="titles" type="text" name="titles" value="" placeholder="titles">
                          <input id="texts" type="text" name="texts" value="" placeholder="texts">
                          <input type="submit" value="Search">
                      </form>
                  </div>
              </div>
          </nav>
      </header>

      <script src="{% static 'js/choices.js' %}"></script>
      <script>
          var textPresetVal = new Choices('#choices-text-preset-values', {
              removeItemButton: true,
          });
          
          var coll = document.getElementsByClassName("collapsible");
          var i;
          for (i = 0; i < coll.length; i++) {
              coll[i].addEventListener("click", function() {
                  this.classList.toggle("active");
                  var content = this.nextElementSibling;
                  if (content.style.maxHeight){
                      content.style.maxHeight = null;
                  } else {
                      content.style.maxHeight = content.scrollHeight + "px";
                  }
              });
          }
      </script>
{% block content %}
{% endblock content %}
    </body>
</html>

```
main.css의 내용은 첨부하지 않는다. 양이 너무 많고, 어차피 위 두 링크에서 확인 가능하다. 

#### 결과 

**검색어 복수 입력한 상태 & 상세 검색 접힌 상태**
![](https://cdn.steemitimages.com/DQmdoT1qkephkiGq81yoaSHeWLcGDGwgcX49yLPwqdQciRt/image.png)

**상세 검색 펼친 상태**
![](https://cdn.steemitimages.com/DQmWpHyEX9GfbMmJCcytWyh9tn6xompMQZCu7b151kZHSCz/image.png)

색상이 너무 강렬하다. 이건 차차 손 봐야겠다. 

***
**[Cookie 😅]**
Python 3.7.4
Django 2.2.4
steem-python 1.0.1
goorm IDE 1.3
👍  , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , and 78 others
properties (23)
authorjune0620
permlinkpython-19-django-12-ui
categoryhive-132971
json_metadata{"app":"peakd/2020.09.4","format":"markdown","image":["https://cdn.pixabay.com/photo/2019/03/12/20/27/kanban-4051777_1280.jpg","https://cdn.steemitimages.com/DQmQukh3k1T2ungVeFwqvT1WecURkGGVmkzZQdsbFwpZGAn/image.png","https://cdn.steemitimages.com/DQmYci2Cf1M6XyaQqz53rkkSSKWttad9merFysHdES5BgMY/image.png","https://cdn.steemitimages.com/DQmdgHuxTVzcrmJGBUz4hCHzBXBZZMn1Hjdo9uzhv8PxTpL/image.png","https://cdn.steemitimages.com/DQmdoT1qkephkiGq81yoaSHeWLcGDGwgcX49yLPwqdQciRt/image.png","https://cdn.steemitimages.com/DQmWpHyEX9GfbMmJCcytWyh9tn6xompMQZCu7b151kZHSCz/image.png"],"links":["https://colorlib.com/wp/free-css3-html5-search-form-examples/","https://www.w3schools.com/howto/howto_js_collapsible.asp"],"tags":["kr","mini","dev","dblog","django","whalepower","palnet","python","goorm"]}
created2020-09-14 12:14:48
last_update2020-09-14 12:26:36
depth0
children0
last_payout2020-09-21 12:14:48
cashout_time1969-12-31 23:59:59
total_payout_value1.167 HBD
curator_payout_value0.997 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length5,510
author_reputation118,592,211,436,406
root_title"[Python #19] [Django #12] 검색 기능 UI 다듬기"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd0
post_id99,621,335
net_rshares9,092,653,477,175
author_curate_reward""
vote details (142)