티스토리 툴바


크리에이티브 커먼즈 라이선스
Creative Commons License
Wicket extension 에는 유용한 컴포넌트들이 많습니다.
그중에서도 AutoCompleteTextField는 자동완성기능 구현을 쉽게 해주는 편리한 컴포넌트 입니다. 
final AutoCompleteTextField<String> field = new AutoCompleteTextField<String>("ac",
            new Model<String>(""))
        {
            @Override
            protected Iterator<String> getChoices(String input)
            {
                if (Strings.isEmpty(input))
                {
                    List<String> emptyList = Collections.emptyList();
                    return emptyList.iterator();
                }

                List<String> choices = new ArrayList<String>(10);

                Locale[] locales = Locale.getAvailableLocales();

                for (final Locale locale : locales)
                {
                    final String country = locale.getDisplayCountry();

                    if (country.toUpperCase().startsWith(input.toUpperCase()))
                    {
                        choices.add(country);
                        if (choices.size() == 10)
                        {
                            break;
                        }
                    }
                }

                return choices.iterator();
            }
        };
        form.add(field);

위 예제는  http://wicketstuff.org/wicket/ajax/autocomplete 에서 발췌한 예제의 일부입니다. AutoCompleteTextField 는 TextField를 확장하며 통상 getChoices를 재정의 해서 검색결과를 Iterator로 리턴하면 검색결과를 아래에 출력해 줍니다.

일반적인 경우 이것으로도 충분하나 단순한 문자열이 아니라 객체이며 검색된 목록에서 보여지는 값과 텍스트값이 다를 경우가 있습니다. 이럴경우 IAutoCompleteRenderer를 구현하거나 서브클래스를 확장하여 AutoCompleteTextField를 커스터마이징 할 수 있습니다.

AbstractAutoCompleteRenderer aa = new AbstractAutoCompleteRenderer() {


@Override

protected void renderChoice(Object object, Response r,

String criteria) {

UserObject user = (UserObject)object;

String str01 = (String)user.getDetail("str01");

String display = user.getFullname() +" ("+(!StringUtils.isEmpty(str01) ? str01 : user.getUsername())+")";

r.write(display);

}


@Override

protected String getTextValue(Object object) {

UserObject user = (UserObject)object;

return user.getFullname() +" ("+user.getUsername()+")";

}

};


위 코드는 AbstractAutoCompleteRenderer에 정의된 renderChoice와 getTextValue 추상메소드 두개를 구현해야 합니다. renderChoice는 검색목록에 표시될 텍스트를 Response.write를 이용해 출력 합니다.  getTextValue는 입력창에 표시될 문자열을 리턴합니다. 

이렇게 간단히 출력할 값만 리턴해 주면 아래와 같이 리스트형식의 목록을 리턴해 줍니다.
<ul>
  <li textvalue="홍길동 (hong)">기술연구소 홍길동</li>
  <li textvalue="이영희 (yhlee)">고객지원팀 이영희</li>
 ...
</ul> 

기본적인 스타일시트가 제공되므로 이렇게만 해도 자동완성기을 구현하는데 문제가 없습니다. 좀 더 다른 형식으로 커스터마이징을 하고자 한다면 IAutoCompleteRenderer를 구현하면 됩니다. 다음의 예제 코드를 참고하세요.

IAutoCompleteRenderer bb = new IAutoCompleteRenderer() {


@Override

public void render(Object object, Response r, String criteria) {

UserObject user = (UserObject)object;

r.write("<li textvalue=\""+user.getFullname()+" ("+user.getUsername()+"\"'>");

r.write(user.getFullname() +" ("+user.getDetail("str01")+")");

r.write("</li>");

}


@Override

public void renderHeader(Response r) {

r.write("<ul>");

}


@Override

public void renderFooter(Response r) {

r.write("</ul>");

}

};

render 메소드는 이전 예제에서 <li>...</li>에 해당하는 태그를 포함한 문자열을 Response 객체에 출력합니다. renderHead와 renderFooter메소드는 시작과 끝부분에 <ul> 과 </ul>에 해당하는 부분을 출력합니다. 이렇게 IAutoCompleteRenderer를 구현하면 리스트가 아닌 div나 p태그등을 이용해 자동완성 기능을 얼마든지 커스터마이징 할 수 있습니다.

이제 AutoCompleterTextField 의 생성자에 Renderer를 인수로 전달하면 됩니다.

final AutoCompleteTextField<UserObject> input = new AutoCompleteTextField<UserObject>("input", new Model<UserObject>(), aa) {


@Override

protected Iterator<UserObject> getChoices(String str) {

List<UserObject> result = service.search(str);

if (result != null)

return result.iterator();

return Collections.EMPTY_LIST.iterator();

        

}

};

input.setOutputMarkupId(true);










Posted by chanlee