FreeGridv1.15.1English

콤보 편집기(자동완성)

입력하는 대로 걸러지는 목록이 있는 콤보: 화살표로 고르고, 자유 입력 또는 목록 값만 허용하며, 비동기 options 함수로 서버를 검색합니다.

실행 예제콤보 편집기

입력하며 걸러 보기, 목록 값만 허용, 서버 검색.

이 데모의 코드
import { createGrid, type ColumnDef, type Row } from '@freegridjs/core';
import { makeRows } from '../data';
import { button, separator, text, tr, type DemoContext } from '../ui';

const CITIES = ['Seoul', 'Busan', 'Incheon', 'Daegu', 'Daejeon', 'Gwangju', 'Ulsan', 'Suwon', 'Tokyo', 'Osaka', 'Paris', 'Berlin', 'Madrid', 'London', 'New York'];
const KO: Record<string, string> = { Seoul: '서울', Busan: '부산', Incheon: '인천', Daegu: '대구', Daejeon: '대전', Gwangju: '광주', Ulsan: '울산', Suwon: '수원', Tokyo: '도쿄', Osaka: '오사카', Paris: '파리', Berlin: '베를린', Madrid: '마드리드', London: '런던', 'New York': '뉴욕' };
export default function mount(ctx: DemoContext) {
  const h = (en: string, ko: string) => tr(ctx.lang, { en, ko });
  const options = CITIES.map(c => ({ value: c, label: ctx.lang === 'ko' ? KO[c] : c }));
  // a fake server: answers after 300 ms with the matching cities
  const search = (_row: Row, q: string) => new Promise<typeof options>(res => setTimeout(() => res(options.filter(o => o.label.toLowerCase().includes(q.toLowerCase()))), 300));
  const data = makeRows(200).map((r, i) => ({ ...r, city: CITIES[i % CITIES.length], hub: CITIES[(i * 3) % CITIES.length], remote: CITIES[(i * 7) % CITIES.length] }));
  const grid = createGrid(ctx.host, {
    columns: [
      { field: 'name', header: h('Name', '이름'), width: 150 },
      { field: 'city', header: h('City (free text)', '도시(자유 입력)'), width: 150, editable: true, editor: { type: 'combo', options } },
      { field: 'hub', header: h('Hub (listed only)', '거점(목록만)'), width: 150, editable: true, editor: { type: 'combo', options, free: false } },
      { field: 'remote', header: h('Server search', '서버 검색'), width: 150, editable: true, editor: { type: 'combo', options: search, free: false } },
    ],
    data, locale: ctx.lang,
  });
  grid.on('cellValueChanged', e => ctx.log(`${e.colId} = ${String(e.newValue)}`));
  grid.on('validationFailed', e => ctx.log(`refused: ${String(e.value ?? '')} — ${e.message}`));
  text(ctx, h('Type to filter (ㅅㅇ works in Korean), ↓ ↑ to pick, Enter to save. The hub column refuses cities that are not listed.',
    '입력하면 걸러지고(초성 ㅅㅇ도 됨) ↓ ↑로 고르고 Enter로 저장합니다. 거점 컬럼은 목록에 없는 도시를 받지 않습니다.'));
  return grid;
}

editor: { type: 'combo' }는 입력하는 대로 아래 목록이 걸러지는 입력칸입니다. 도시·상품·거래처처럼 목록이 길어 select로 찾기 힘들 때 좋습니다. 대소문자를 구분하지 않고 한글 초성도 알아봅니다(ㅅㅇ으로 서울).

기본 사용

const cities = [{ value: 'SEL', label: 'Seoul' }, { value: 'BSN', label: 'Busan' }, { value: 'ICN', label: 'Incheon' }];
createGrid(el, {
  columns: [
    // free text allowed (the default): a city not in the list is kept as typed
    { field: 'city', editable: true, editor: { type: 'combo', options: cities } },
    // only listed values: anything else is refused with a message
    { field: 'hub', editable: true, editor: { type: 'combo', options: cities, free: false } },
  ],
  data,
});

키보드와 마우스

키동작
입력목록을 거름(이름이나 값에 글자가 들어 있으면)
↓ / ↑강조 이동. 입력칸에 강조된 옵션이 보임
Enter강조된 옵션 또는 입력한 글자(자유 입력)를 저장. free: false면 첫 일치 항목이 강조되어 몇 글자 뒤 Enter로 고름
항목 클릭바로 저장
Esc저장하지 않고 닫기

옵션

이름타입설명
optionsSelectOption[] | (row, query) => SelectOption[] | Promise<SelectOption[]>선택지: 값 또는 { value, label, disabled }. 함수면 행과 입력한 글자를 받고, 입력할 때마다(마지막 키 150ms 뒤) 다시 불리며 Promise를 돌려줘도 됩니다. 기다리는 동안 목록에 불러오는 중… 이 보입니다.
freeboolean목록에 없는 글자도 받을지(기본 true). false면 목록에 있는 사용 가능한 값만 저장하고, 다른 글자 붙여넣기는 건너뜁니다.

서버 검색

{ field: 'customerId', header: 'Customer', editable: true,
  editor: {
    type: 'combo',
    free: false,
    // called with what is typed; answers that arrive late for an older query are dropped
    options: async (row, query) => {
      const res = await fetch('/api/customers?q=' + encodeURIComponent(query));
      const list = await res.json();
      return list.map(c => ({ value: c.id, label: c.name }));
    },
  },
  // show the name for the stored id (the cell keeps the id)
  valueGetter: row => row.customerName ?? row.customerId,
}

함수로 주면 그리드는 모든 옵션을 미리 알 수 없습니다. 셀에는 저장된 값이 보이므로(이름을 보이려면 valueGetter나 renderer를 쓰세요) free: false일 때 붙여넣은 글자는 확인할 수 없어 거부됩니다.

셀 표시와 저장 값

  • 고정 목록이면 셀에는 옵션 이름이 보이고 값이 저장됩니다(SEL 저장, Seoul 표시).
  • 붙여넣기는 이름이나 값을 대소문자 상관없이 받습니다.
  • free: false이고 목록이 고정인 콤보는 이름으로 된 값 목록 필터가, 자유 입력 콤보는 텍스트 필터가 붙습니다. 편집기 컬럼의 필터를 보세요.

이 페이지에 대한 질문

서버를 검색하는 자동완성 셀을 만들려면?

콤보의 options를 함수로 주세요: editor: { type: 'combo', options: (row, q) => fetch('/api?q=' + q).then(r => r.json()) }. 입력할 때마다(잠깐 기다렸다가) 불리고 Promise를 돌려줘도 됩니다.