품목 검색은 목록을 띄우고 하나 고르면 끝나는 기능처럼 보인다. 하지만 실제 작성자는 수량부터 적기도 하고 여러 제품을 찾아 한 번에 넣기도 하며 이전 거래에서 쓰던 단가를 확인하기도 한다. 이 작업의 요청에는 작은 팝업, 선택한 순서대로 넣기, 더블클릭 적용, 현재 선택의 색상 표시가 차례로 나온다. 나는 이런 세부 요구가 검색 기능의 장식이 아니라 이미 한 일을 보존하는 규칙이라고 본다.

검색창을 열기 전의 행부터 보존한다

현재 행에 수량과 단가만 써 놓은 상태에서 제품을 선택할 수 있다. 그때 제품 기본값으로 행 전체를 교체하면 사용자가 먼저 쓴 숫자를 잃는다. 반대로 이미 품목 설명이 있는 행을 무조건 덮어쓰면 다른 거래가 사라진다. 보관된 선택 코드에는 내용이 없는 행을 재사용할지, 기존 행 다음에 새 줄을 넣을지를 판단하는 경계가 드러나 있다.

나는 이 판단을 예제로 먼저 설명하는 편이 좋다고 본다. 완전히 빈 줄, 수량만 있는 줄, 이름만 직접 쓴 줄, 이미 제품이 연결된 줄을 나란히 놓고 같은 선택을 적용해 본다. 어디는 기존 값을 유지하고 어디는 새 줄이 생기는지 말로 합의한다. 화면을 만든 다음 테스트 숫자를 맞추기보다 사용자가 입력을 잃지 않는 규칙을 먼저 정하면 오류를 발견하기도 쉽다.

현재 위치와 여러 개 선택을 섞지 않는다

키보드로 이동한 현재 항목과 체크한 품목 묶음은 다른 상태다. 한 항목을 가리키는 색상이 화면 상단에 남아 있으면 사용자는 자신이 어느 제품에 작업하는지 오해한다. 여러 개를 선택할 때는 체크한 순서를 따로 유지해야 한다. 검색어가 바뀌거나 페이지를 넘겼다는 이유로 기존 선택이 사라지는지도 확인할 필요가 있다.

이 구현의 선택 목록은 새 항목을 뒤에 추가하고 같은 항목을 다시 누르면 해제하는 방식이다. 그 목록을 입력 줄로 옮기는 순서도 유지한다. 더블클릭 바로 넣기는 이미 체크한 묶음과 어떤 관계인지 결정해야 한다. 두 경로가 겹쳐 같은 제품이 두 번 들어가는 경우를 막으려면 실제 이벤트가 어느 동작을 한 번 실행하는지 확인해야 한다. 선택 표시가 맞는 것과 삽입 결과가 맞는 것은 별도 검사다.

거래처별 목록은 편리한 기본값이다

당시 요청에는 거래처가 과거에 많이 주문한 품목을 우선 보여 달라는 조건이 있다. 이후 매입용 요청서에서는 선택한 공급처에 연결된 품목을 중심으로 검색하도록 범위가 세분화됐다. 이때 고객의 판매 이력과 공급처의 매입 이력을 같은 순위로 섞으면 엉뚱한 추천이 된다. 문서의 역할과 선택된 거래처가 검색 조건에도 이어져야 한다.

관련 이력이 없을 때 다른 업체 품목을 조용히 대신 보여 주는 방식도 피하는 편이 좋다. 연결된 품목이 없다는 사실을 알리고 전체 목록으로 바꿀 수 있게 하면 된다. 자주 쓰는 제품을 빨리 찾게 하는 정렬은 도움이고, 거래처가 취급하는 품목의 사실을 확정하는 근거는 아니다. 화면의 기본값과 사용자가 직접 바꾼 선택을 구분하면 빠른 입력과 예외 처리가 함께 가능해진다.

작은 팝업도 예외 입력으로 검사한다

화면 가장자리에서 검색을 열거나 키보드가 올라온 상황에서는 팝업 위치가 달라져야 한다. 보관된 코드에는 보이는 화면 범위를 기준으로 위치를 보정하는 함수가 있다. 그렇다고 함수가 존재한다는 사실만으로 실제 휴대전화에서 키보드와 검색이 편하다고 말할 수는 없다. 현재 입력 행을 찾을 수 있는지, 닫힌 뒤 초점이 어디로 가는지도 별도의 사용 검수다.

공유할 수 있는 핵심은 예쁜 검색창 모양보다 상태를 나누는 방법이다. 검색 조건, 현재 항목, 선택 목록, 대상 행, 삽입 결과를 구분하면 무엇이 사라졌는지 추적할 수 있다. 이번 글은 선택한 원본 요청과 보관된 코드에서 이 규칙을 읽어 재구성했다. 실제 고객 자료나 원래 화면을 재실행하지 않았으며, 새 화면을 검토한다면 행 제한에 걸린 경우에도 기존 입력이 그대로 남는지까지 확인할 것이다.