서비스 프레임워크 설명서 |
상세 검색 기능을 추가해보자. 상세 검색 기능에서는 키워드 외에 기간과 정렬 조건을 검색 조건에 추가할 수 있게 하였다. 상세 검색을 위한 폼을 아래와 같이 먼저 추가한다. (가독성을 위해 태그 및 태그 속성들은 생략했다.)
1. … 2. <a data-target="#detailed-search" role="button" class="btn btn-link" data-toggle="collapse"> <small>상세 검색</small> </a> 3. … 4. <form name="detailed-search-form" class="form-horizontal" role="form"> 5. <div id="detailed-search" class="box box-bordered collapse"> 6. … 7. <labe>키워드</label> 8. <input type="text" name="query" class="form-control" /> 9. <label>기간</label> 10. <label><input type="radio" name="date-range" value=""/> 전체</label> 11. <label><input type="radio" name="date-range" value="d"/> 최근 1일</label> 12. <label><input type="radio" name="date-range" value="w"/> 최근 1주</label> 13. <label><input type="radio" name="date-range" value="m"/> 최근 1달</label> 14. <label><input type="radio" name="date-range" value="y"/> 최근 1년</label> 15. <label><input type="radio" name="date-range" value="r"/> 직접입력</label> 16. <input type="text" name="date-from"/> - <input type="text" name="date-to"/> 17. <label>정렬</label> 18. <label><input type="radio" name="sort" value=""/> 정확도</label> 19. <label><input type="radio" name="sort" value="regdate desc"/> 최신순</label> 20. <button type="submit" class="btn btn-primary">검색</button> 21. <button type="reset" class="btn" id="reset">초기화</button> 22. … 23. </div> 24. </form> 25. …
추가된 폼은 아래와 같이 표시된다.
"상세 검색" 앵커 클릭 시 "상세 검색" 폼이 보이게 하는 것은 bootstrap의 Collapse를 활용하였다.
상세 검색 후 페이지 이동 시 혹은 금칙어, 추천 검색어, 오타 교정 등의 처리를 위해 키워드 검색 폼(search-form)이 포함하는 p, original-query 등의 입력 필드 값들도 함께 서버로 전달되어야 한다. 이를 위해 상세 검색 폼(detailed-search-form)의 검색 버튼 클릭 시 상세 검색 폼을 제출하지 않고 사용자가 입력한 검색 조건들을 키워드 검색 폼에 복사 후 사용자 검색 폼을 제출한다.
아래와 같이 키워드 검색 폼에 상세 검색 폼의 검색 조건들을 추가한다. 페이지 이동 시 검색 조건이 유지될 수 있게 하기 위해 각 앨리먼트의 값들은 요청 파라미터 값들로 초기화한다.
1. …
2. <form name="search-form" method="post" class="form-inline"
role="form">
3. …
<input type="hidden" id="date-range" name="date-range"
value="${param['date-range']}"/>
4. <input type="hidden" id="date-from" name="date-from"
value="${param['date-from']}"/>
5. <input type="hidden" id="date-to" name="date-to"
value="${param['date-to']}"/>
6. <input type="hidden" id="sort" name="sort"
value="${param['sort']}"/>
7. </form>
8. …
이렇게 키워드 검색 폼에 상세 검색 폼의 검색 조건들을 복사하지 않고 페이지 이동 등을 처리하기 위해 세션 변수에 처음 검색 조건을 저장한 후, 페이지 이동 시 세션 변수에 저장된 검색 조건을 재사용할 수도 있다. (세션 변수를 너무 많이 사용하면 WAS가 사용할 수 있는 가용 메모리가 줄어들므로 가급적 세션 변수 사용은 자제하는 것이 바람직하다.)
이제 상세 검색과 관련된 자바스크립트를 작성해 보자. 먼저 상세 검색 폼의 각 검색 조건을 키워드 검색 폼에 초기화된 값들로 일치시켜 상세 검색 폼을 보여줄 때 현재 검색 조건을 확인할 수 있게 한다.
1. $(function() {
2. …
3. $f = $("form[name=detailed-search-form]");
4. $f.find("input[name=query]").val($("#query").val());
5. $f.find("input[name=date-range]").filter("[value="+
$("#date-range").val() + "]").prop("checked",true);
6. $f.find("input[name=date-from]").val($("#date-from").val());
7. $f.find("input[name=date-to]").val($("#date-to").val());
8. $f.find("input[name=sort]").filter("[value=\""+
$("#sort").val()+"\"]").prop("checked",true);
9. });
다음 상세 검색 폼 제출 시 검색 조건들을 키워드 검색 폼으로 복사하고 키워드 검색 폼을 대신 제출한다.
10. $f.on("submit", function(e) {
// 상세 검색 폼이 제출되지 못하도록 디폴트 핸들러 실행을 막는다.
11. e.preventDefault();
// 검색 조건들을 키워드 검색 폼으로 복사한다.
12. $("#date-range").val($f.find("input[name=date-range]:checked")
.val());
13. $("#date-from").val($f.find("input[name=date-from]").val());
14. $("#date-to").val($f.find("input[name=date-to]").val());
15. $("#sort").val($f.find("input[name=sort]:checked").val());
16. $("#query").val($f.find("input[name=query]").val());
// 키워드 검색 폼을 제출한다.
17. $("form[name=search-form]").submit();
18. });
상세 검색의 경우 검색 조건이 복잡해졌다. 검색 조건으로부터 SearchQuery 객체를 만드는 클래스를 아래와 같이 SearchQueryBuilder 라는 이름으로 구현한다.
1. <%!public static class SearchQueryBuilder {
2. private String query;
3.
4. public SearchQueryBuilder(String query) {
5. this.query = query;
6. }
7.
8. public SearchQuery getSearchQuery(HttpServletRequest request) {
9. QueryBuilder qb = new QueryBuilder();
// 키워드 검색 조건
10. qb.whereColumnEquals("text_idx", query, "allwordthruindex");
11. String dateRange = RequestUtils.getParameter
(request, "date-range");
12. if ("r".equals(dateRange)) {
// 기간이 직접 입력일 경우
13. qb.whereColumnInDateRange("regdate",
RequestUtils.getParameter(request, "date-from"),
RequestUtils.getParameter(request, "date-to"));
14. } else {
// 기간이 전체, 최근1일, 최근1주, 최근1달, 최근1년일 경우
15. qb.whereColumnInDateRange("regdate", dateRange);
16. }
// 정렬 기준
17. qb.orderBy(RequestUtils.getParameterValues(request, "sort"));
18.
19. SearchQuery sq = new SearchQuery("sample", query);
20. sq.setLimit(RequestUtils.getParameterInt(request, "rpp", 10));
21. sq.setOffset(RequestUtils.getParameterInt(request, "p", 0)
* sq.getLimit());
22. sq.setWhereClause(qb.getWhereClause());
23. sq.setSortingClause(qb.getSortingClause());
24. return sq;
25. }
26. }
27. %>
이제 SearchQueryBuilder를 이용해서 검색 결과를 구하도록 JSP 스크립트를 변경한다.
1. …
2. CrzClient crzclient = new CrzClient("127.0.0.1", 9577);
3. SearchQueryBuilder builder = new SearchQueryBuilder(query);
4. SearchQuery sq = builder.getSearchQuery(request);
5. SearchResultSet srs = crzclient.search(sq);
6. …