IgrGrid ではテンプレート機能を使用してセルにカスタムの要素を配置することができます。
セルが非編集時に使用されるのがセルテンプレート( bodyTemplate )、編集モード時に使用されるのがセル編集テンプレート( inlineEditorTemplate )です。

ここでは、セルにチェックボックス( <input type=checkbox> )とセレクトボックス( <select> )を表示するサンプルを作成します。以下のように、「check」列と「status」列を定義し、それぞれに bodyTemplate と inlineEditorTemplate プロパティを設定します。

<IgrGrid ..... >
	<IgrColumn
	  field="check"
	  header="Check"
	  cellClasses={checkboxDisplayClasses}
	  editable={true}
	  bodyTemplate={checkBoxTemplate}
	  inlineEditorTemplate={editCheckBoxTemplate}
	></IgrColumn>
	<IgrColumn 
	  field="status" 
	  header="Status" 
	  editable={true} 
	  bodyTemplate={comboCellTemplate} 
	  inlineEditorTemplate={editComboTemplate}
	></IgrColumn>
.....
</IgrGrid>

チェックボックスセルの非編集時のテンプレートである checkBoxTemplate 、編集モード時のテンプレート editCheckBoxTemplate 、セレクトボックスセルの非編集時のテンプレート comboCellTemplate 、編集モード時のテンプレート editComboTemplate は以下のようにファンクションを作成します。

// チェックボックス表示用テンプレート
const checkBoxTemplate = (ctx: IgrCellTemplateContext) => {
  const handleMouseDown = (event: React.MouseEvent<HTMLInputElement>) => {
     ctx.cell.value = !(event.target as HTMLInputElement).checked;
  };
  return (
      <span>
          <input
          type="checkbox"
          defaultChecked={ctx.cell.value}
          onMouseDown={handleMouseDown}
        />
      </span>
  );
};

// チェックボックス編集用テンプレート
const editCheckBoxTemplate = (ctx: IgrCellTemplateContext) => {
  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    ctx.cell.editValue = event.target.checked;
  };

  return (
    <initial-focus>
      <span>
          <input
          type="checkbox"
          defaultChecked={ctx.cell.value}
          onChange={handleChange}
        />
      </span>
    </initial-focus>
  );
};

// セレクトボックス表示用テンプレート
const comboCellTemplate = (ctx: IgrCellTemplateContext) => {
  return <span>{ctx.cell.value}</span>;
};

// セレクトボックス編集用テンプレート
const editComboTemplate = (ctx: IgrCellTemplateContext) => {
  const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    ctx.cell.editValue = event.target.value;
  };

  return (
    <initial-focus>
      <select 
      defaultValue={ctx.cell.value} 
      onChange={handleChange} 
      className="editor-template">
        {statusOptions.map((option) => (
          <option key={option} value={option}>
            {option}
          </option>
        ))}
      </select>
    </initial-focus>
  );
};

上の実装で、editCheckBoxTemplate と editComboTemplate 内の <input> および <select> タグは、 <initial-focus> タグで囲まれています。これは、セルが編集モードに入った際にこれらの要素にフォーカスを当てる処理を行うためです。この処理により、タブキー等でセルの遷移をしながらキーボード操作によってセルを編集することが可能になります。
<initial-focus> タグを使用するためのInitialFocusクラスは以下のように定義します。

declare module "react/jsx-runtime" {
  namespace JSX {
    interface IntrinsicElements {
      "initial-focus": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
    }
  }
}

class InitialFocus extends HTMLElement {
    constructor() { super(); }
    connectedCallback() {
        setTimeout(() => {
            const input = this.querySelector('input,select');
            (input as any).focus();
            (input as any).select && (input as any).select();
        }, 0);
    }
}
customElements.define('initial-focus', InitialFocus);
Tagged: