일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- react-router-dom
- 냥빨이다가온다
- 언젠간가겠지
- 내배위의고양이
- 클래스 토글
- chart responsive
- 를
- ROUTER 버전6
- classList toggle
- classList add
- classList
- classList remove
- 포트폴리오
- windowwidth
- 접근성
- className
- 대표님물리기없기
- 2020
- 퍼블리싱
- 커스텀훅
- react-router
- 안짤렸다
- 방심은금물
- chart.js
- react
- 리엑트할수있는퍼블리셔라규
- resize
- 간식금지다!
- Today
- Total
틈
[2021-05-24] 검색화면(with JSON) 본문
JSON 을 ajax로 불러와서 검색하면을 만드는 프로젝트를 진행하였습니다.
<div class="container">
<div class="header">
<div class="title">패스트푸드점 찾기</div>
<div class="search">
<input type="text" id="text-search">
<button class=btn-search>검색</button>
</div>
</div>
<div class="body">
<div class="total"></div>
<div class="list">
<div id="item-template" class="item">
<div class="item-no"></div>
<div class="item-detail">
<div class="item-name"></div>
<div class="item-addr"></div>
</div>
</div>
</div>
</div>
<div class="paging"></div>
</div>
@charset "UTF-8";
* {box-sizing:border-box;}
:before,:after {display:none;content:"";}
.container {width:400px;margin:50px auto 80px}
.header {position:relative;background-color: #6a7486;border-radius: 3px;padding: 10px 20px;min-height: 50px;}
.title {display:inline-block;font-size: 16px;color: #fff;vertical-align: middle;font-weight: bold;}
.search {display:inline-block;position:absolute;right:20px;}
.search input {padding:5px;min-height:30px;}
#txt-search {width:300px;height:30px;border:1px solid #ffecd9;border-radius:7px;background-color:#fff6eb;vertical-align:middle;outline:none;text-indent:10px;font-size:17px;}
.btn-search {width:70px;height:30px;background-color: #45484c;margin-left:3px;vertical-align:middle;outline : none;border: 0;cursor:pointer;font-size: 14px;font-weight: bold;color: #fff;}
.total {margin:20px 10px 7px;font-size:13px;color:#bd5a00;}
#item-template {display:none;}
.item {padding:10px 20px;border:1px solid #d2d2d2;border-radius:14px;margin-bottom:10px;}
.item-no {display:inline-block;padding-left:10px;padding-right:10px;font-size:30px;color:#a0a0a0;vertical-align:middle;min-width:17px;}
.item-detail {display:inline-block;margin-left:10px;vertical-align:middle;}
.item-name {font-size:20px;}
.item-addr {font-size:14px;color:#909090;margin-top:2px;}
.paging {text-align:center;}
.paging a {display:inline-block;position:relative;width:20px;height:20px;margin:0 2px;background-color:#444;font-size:14px;text-decoration:none;vertical-align:middle;color:#fff;}
.paging a.current {background-color:#fff;border:1px solid #999;color:#333;}
.paging a:first-child,.paging a:last-child {font-size:0;line-height:0;background-color:#fff;border:1px solid #ddd;}
.paging a:first-child:before,.paging a:last-child:before {display:block;position: absolute;top: 5px;left: 7px;width:7px;height:7px;border-top:1px solid #999;border-left:1px solid #999;transform:rotate(-45deg);}
.paging a:last-child:before {left:auto;right: 8px;transform:rotate(135deg);}
var API_URL = "http://floating-harbor-78336.herokuapp.com/fastfood";
var $searchInput,$searchBtn,$total,$list,$paging;
$(function(){
$searchInput = $('#text-search');
$searchBtn = $('.btn-search');
$total = $('.total');
$list = $('.list');
$paging = $('.paging');
$searchBtn.on('click', function(){
var searchKwd = $searchInput.val();
search(1, 10, searchKwd);
});
$searchInput.on('keypress', function(e){
if(e.keyCode === 13){
$searchBtn.trigger('click');
}
})
})
function search(page, perPage, searchKwd){
$.get(API_URL, {
page : page,
perPage : perPage,
searchKeyword : searchKwd
}, function(data){
var list = data.list;
var total = data.total;
$total.html('총 ' +total+ '개를 검색했습니다.');
$list.find($('.item:not(#item-template)')).remove();
for(var i = 0;i < list.length;i++){
var $item = $('#item-template').clone().removeAttr('id');
var elem = list[i];
$item.find('.item-no').html(i+1);
$item.find('.item-name').html(elem.name);
$item.find('.item-addr').html(elem.addr);
$list.append($item);
}
paging(page, perPage, searchKwd, total);
})
}
function paging(page, perPage, searchKwd, total){
var setPage = 5;
var startPage = Math.floor((page - 1) / setPage) * setPage + 1;
var endPage = startPage + setPage - 1;
var totalPage = Math.floor(total / setPage);
if(endPage > totalPage){
endPage = totalPage;
}
$paging.empty();
var prevPage = page - 1;
var nextPage = page + 1;
if(prevPage < 1){
prevPage = 1;
}
if(nextPage > totalPage){
nextPage = totalPage;
}
$prev = $('<a href="javascript:search(' + prevPage + ',' + perPage +', \'' +searchKwd + '\')">이전</a>');
$paging.append($prev);
for(var i = startPage;i <= endPage;i++){
var p = $('<a href="javascript:search(' + i + ',' + perPage +', \'' +searchKwd + '\')">' +i+'</a>');
if(page === i){
p.addClass('current');
}
$paging.append(p);
}
$next = $('<a href="javascript:search(' + nextPage + ',' + perPage +', \'' +searchKwd + '\')">다음</a>');
$paging.append($next);
}
(code Pen으로 publishing 하고 싶었으나 code Pen에서 async 기능을 block 처리하는 관계로 코드 노출합니다.)
위 코드는 『자바스크립트 프론트엔드 프로젝트 가이드』에 나오는 예제입니다.
최근 JSON 사이드 프로젝트를 진행하면서 연관된 내용이라 재미있게 진행했습니다. 특히 paging 부분이 흥미로웠습니다. 친한 개발자 중에 paging을 계속 빼먹는 분이 계시는데, 그 분의 기분이 이해되는 프로젝트 였습니다 ㅎㅎ(책에서도 매우 귀찮은 작업이라고 소개하고 있습니다.) 처음 하는 저는 paging이 굉장히 흥미롭고 재미있는 작업이었는데, 확실히 계속 이 코드를 짜라고 하면 귀찮은 작업이 될 것 같다고 생각했습니다.
Ajax를 통해 데이터를 가져오는 작업에서 가장 문제가 되는 부분이 코드 노출이었습니다. 유지보수를 진행하는 측에서는 코드노출이 필요하고, 작업효율 면에서는 DOM에 데이터를 심어서 스크립트 코드로 퍼블리싱 하는 방법이 더 효율적인데, '양쪽 다 만족할 수 있을까?'를 계속 생각했고, .clone()을 통해서 코드노출과 데이터를 넣는 두가지 방법을 모두 만족할 수 있었습니다. 앞으로 유용하게 활용할 예정입니다.
해당 책이 초반에는 바닐라 js로 작업하는 방식으로 시작하다가 aync부분에서 jQuery를 사용할 수 밖에 없었는데, XMLHttpRequest 부분이 잘 작동하지 않는 것을 보고 어쩔 수 없는 부분을 실감했습니다.
책의 마지막 프로젝트와 함께 돌아오겠습니다~!
'code > Daily Side Project' 카테고리의 다른 글
[2021-06-02] 그래프 (0) | 2021.06.02 |
---|---|
[2021-05-27] JSON과 파라미터로 타입이 다른 2개의 화면 표출 (0) | 2021.05.27 |
[2021-05-20] 배열로 된 데이터를 객체로 반환하기 (0) | 2021.05.20 |
[2021-05-19] 클래스로 구구단 만들기 (0) | 2021.05.19 |
[2021-05-19] 이미지 드래그 예제 (0) | 2021.05.19 |