Input ComboBox(콤보박스) 항목으로 FlexGrid(그리드)를 추가하는 방법
페이지 정보
작성자 GCK루시 작성일 2022-08-08 11:29 조회 972회 댓글 0건본문
관련링크
코로나 바이러스 유행이 여전히 만연한 지금 바이러스 유행 전 후로 가장 두드러진 변화는 디지털 서비스에 대한 의존도가 높아졌다는 점입니다. 그만큼 온라인에서 제공하는 서비스가 다양해지고 개발의 중요성도 더욱 강조되고 있습니다.
이런 트렌드와 함께 프론트엔드 개발 영역에서 JavaScript(자바스크립트)는 해마다 그 위치가 확고해지고 있으며 개발자들은 더 좋은 사용자 경험을 제공하기 위해 최신 기술을 지닌 UI를 개발하도록 압박 받고 있습니다.
그중 하나는 아마도 사용자가 정확한 정보를 입력하게 유도하여 신속하고 정확하게 유의미한 정보를 수집하고, 이를 가공할 수 있게 웹 상의 입력 화면을 구현하는 것일 것입니다.
이를 위해 GrapeCity에서는 개발자분들을 위해, 다양한 Wijmo Input 컨트롤을 제공하고 있고, 이를 더욱 확장하여 원하는 방식의 입력 화면을 개발할 수 있도록 도움을 드리고 있습니다.
이번 포스팅에서는 가장 많이 사용하시는 Input 컨트롤의 ComboBox(콤보박스)에 텍스트가 아닌 FlexGrid(그리드) 요소를 추가하여 커스터마이징 하는 방법에 대해서 안내드리겠습니다.
이를 통해, 콤보박스 안에서 단순히 단일 값을 선택하는 것을 넘어, 해당 선택 값에 대한 더욱 많은 정보를 보여줌으로써 사용자에게 더욱 정확한 정보를 선택할 수 있도록 도움을 줄 수 있습니다.
실제로 구현된 화면은 아래와 같으며, 상단의 HTML / CSS / JS 탭을 통해 소스코드를 확인하고 바로 수정해보실 수 있습니다.
샘플 링크 : DropDown and AutoComplete with FlexGrid (codepen.io)
Wijmo FlexGrid를 DropDown(드롭다운)으로 갖는
ComboBox 구현하기
아래 과정을 통해서 위의 샘플과 동일한 결과물을 만들 수 있습니다.
* 전체 소스 코드는 상단 라이브 샘플 화면의 HTML / CSS / JS 탭을 누르시면 확인이 가능합니다.
A-1. 먼저 Wijmo 컨트롤을 사용하기 위해 HTML의 head 태그 안에 Wijmo 파일을 추가 해줍니다.
<link rel="stylesheet" href="https://cdn.grapecity.com/wijmo/5.latest/styles/wijmo.min.css" /> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous" /> <script src="https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.min.js"></script> <script src="https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.grid.min.js"></script> <script src="https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.input.min.js"></script>
A-2. Wijmo의 ComboBox 컨트롤을 DOM 요소에 할당할 'theComboTable'라는 id를 가진 div 요소를 HTML 파일에 생성합니다.
<div id="theComboTable"></div>
A-3. ComboBox에 추가할 데이터 함수를 생성합니다.
function getData() { return [ { id: 1, country: "Luxembourg", gdpm: 57825, popk: 563, gdpcap: 102708 }, { id: 2, country: "Switzerland", gdpm: 664005, popk: 8238, gdpcap: 80602 }, { id: 3, country: "Norway", gdpm: 388315, popk: 5205, gdpcap: 74604 }, { id: 4, country: "Macao", gdpm: 46178, popk: 647, gdpcap: 71372 }, { id: 5, country: "Qatar", gdpm: 166908, popk: 2421, gdpcap: 68941 }, { id: 6, country: "Ireland", gdpm: 283716, popk: 4635, gdpcap: 61211 }, ]; }
A-4. ComboBox 컨트롤의 인스턴스를 생성한 후, itemsSource에 데이터 함수를 호출하여 데이터를 할당하고 속성을 설정해 줍니다.
function init() { let theComboTable = new wijmo.input.ComboBox("#theComboTable", { headerPath: "country", //input 요소에 표시되는 값을 가져오는데 사용할 속성의 이름 설정 displayMemberPath: "country", // 항목의 시각적 표현으로 사용할 속성의 이름을 설정 itemsSource: getData(), // 데이터 바인딩 }); }
A-5. 드롭다운 안에 FlexGrid를 넣을 요소를 createElement 메서드를 호출하여 생성 한 뒤, theComboTable의 드롭다운에 해당 요소를 append 해줍니다.
- createElement 메서드는 HTML 문자열로부터 요소를 생성하는 메서드입니다.
var gridDiv = wijmo.createElement("<div></div>", theComboTable.dropDown);
.wj-dropdown-panel.wj-control.wj-listbox .wj-listbox-item { display: none; }
let grid = new wijmo.grid.FlexGrid(gridDiv, { itemsSource: theComboTable.collectionView, stickyHeaders: true, //머리글 고정 유무 headersVisibility: "Column", // 헤더 가시성 설정 selectionMode: "Row", //선택 모드 isReadOnly: true, //읽기 전용 유무 });
A-8. 드롭다운의 FlexGrid의 셀 클릭 시, 동일 행에 위치한 country 열의 값을 ComboBox의 text로 설정해줄 수 있도록 클릭 이벤트를 추가해 줍니다.
- FlexGrid의 hitTest 메서드를 이용하여 클릭한 영역의 정보를 가져올 수 있습니다.
grid.hostElement.addEventListener("click", (e) => { let hti = grid.hitTest(e); if (hti.panel.cellType == wijmo.grid.CellType.Cell) { //셀을 클릭하면 theComboTable.text = grid.rows[hti.row].dataItem.country; //text 설정 } else { e.preventDefault(); } });
A-9. 드롭다운이 표시될 때 발생하는 isDroppedDownChanged 이벤트 내에서 그리드 invalidate 메서드를 호출하여 갱신시켜 줍니다.
- isDroppedDownChanged 이벤트는 드롭다운이 보이거나 숨김 처리된 후 발생하는 이벤트입니다.
theComboTable.isDroppedDownChanged.addHandler(() => { grid.invalidate(); });
AutoComplete 구현하기
<div id="theAutoTable"></div>
B-2. AutoComplete에 추가할 데이터 함수를 생성합니다.
function getData() { return [ { id: 1, country: "Luxembourg", gdpm: 57825, popk: 563, gdpcap: 102708 }, { id: 2, country: "Switzerland", gdpm: 664005, popk: 8238, gdpcap: 80602 }, { id: 3, country: "Norway", gdpm: 388315, popk: 5205, gdpcap: 74604 }, { id: 4, country: "Macao", gdpm: 46178, popk: 647, gdpcap: 71372 }, { id: 5, country: "Qatar", gdpm: 166908, popk: 2421, gdpcap: 68941 }, { id: 6, country: "Ireland", gdpm: 283716, popk: 4635, gdpcap: 61211 }, ]; }
B-3. AutoComplete 컨트롤의 인스턴스를 생성한 후, itemsSource에 데이터를 할당하고 속성을 설정해 줍니다.
function init() { let auto = new wijmo.input.AutoComplete("#theAutoTable", { headerPath: "country", displayMemberPath: "country", itemsSource: getData(), }); }
B-4. 드롭다운에 추가 할 FlexGrid 호스트 요소를 createElement 메서드를 호출하여 생성한 뒤, append 해줍니다.
var gridDivAuto = wijmo.createElement( "<div class='innerGrid'></div>", auto.dropDown );
.wj-dropdown-panel.wj-control.wj-listbox .wj-listbox-item { display: none; }
B-6. 그 다음 생성한 DOM 요소에 FlexGrid 인스턴스를 생성합니다.
// 그리드 생성 let gridAuto = new wijmo.grid.FlexGrid(gridDivAuto, { itemsSource: auto.collectionView, stickyHeaders: true, headersVisibility: "Column", selectionMode: "Row", isReadOnly: true, });
B-7. AutoComplete 컨트롤 필터링 기능을 위해 아래와 같이 확인 작업을 진행합니다.
AutoComplete 컨트롤에서 input 창에 텍스트를 입력하여 항목을 필터링할 수 있습니다. FlexGrid를 드롭다운 항목으로 가지는 경우에도 필터링이 가능하지만 텍스트 값이 업데이트될 때 드롭다운이 다시 렌더링되고 FlexGrid의 호스트 요소가 드롭다운에서 제거됩니다.
따라서 FlexGrid를 드롭다운에 표시될 수 있도록 isDroppedDownChanged와 loadedItems 이벤트 발생 시, 드롭다운에 그리드가 있는지 확인 후 없으면 다시 추가해 줍니다.
- loadedItems 이벤트는 리스트 항목들이 생성된 후 발생하는 이벤트입니다.
- B-4 단계에서 요소 생성 시 지정한 클래스 이름을 이용하여 그리드의 삭제 유무를 판별할 수 있습니다.
auto.isDroppedDownChanged.addHandler(() => { if (auto.dropDown.querySelector(".innerGrid") == null) { auto.dropDown.appendChild(gridAuto.hostElement); } else { gridAuto.invalidate(); } }); auto.listBox.loadedItems.addHandler((s, e) => { if (auto.dropDown.querySelector(".innerGrid") == null) { auto.dropDown.appendChild(gridAuto.hostElement); } else { gridAuto.invalidate(); } });
이상으로 FlexGrid를 드롭다운 항목으로 갖는 AutoComplete 컨트롤까지 완성했습니다.
이번 포스팅은 컨트롤을 커스터마이징하여 FlexGrid를 드롭다운 항목으로 갖는 input을 구현해 보았습니다. 해당 기능뿐만 아니라 더 다양한 기능을 가진 Wijmo를 사용하여 사용자 친화적이고 강력한 UI를 구현해 보시기 바랍니다.
ComboBox의 기본 데모가 궁금하시다면 여기를 AutoComplete의 기본 데모가 궁금하다면 여기를 클릭하여 주시기 바랍니다.
댓글목록
등록된 댓글이 없습니다.