Ignite UI for Blazor のコンボボックスコンポーネント IgbCombo は、単一選択モード時の既定の動作では、ドロップダウンリストから選択済みアイテムをもう一度クリックすると、その選択が解除されます。しかしながら、一般的な HTML 標準の select/option 要素の代わりに、単一選択モードの IgbCombo を使いたい場合は、この選択が解除されるトグル動作は好ましくないかもしれません。

このような場合は、以下の措置によって、選択済みアイテムを繰り返しクリックしても、選択されたままを維持することが可能です。

まず以下のような JavaScript ファイルを作成し、フォールバックページ (wwwroot/index.html など) でこの JavaScript ファイルを script 要素で参照・読み込むようにしておきます。

(() => {

  // アイテムテンプレートによって自前で構築したコンボボックスアイテムのマスク要素に対する
  // クリックイベントを処理します。
  const comboItemClickHandler = (event) => {

    // 未選択のアイテムであれば、これ以上、とくに何もせず既定の動作に任せます。
    const comboItem = event.target.parentElement;
    if (comboItem.ariaSelected !== "true") return;

    // もしも既に選択済みのアイテムであれば、マウスクリックイベントの伝達を止めて、既定の
    // 動作をキャンセル。
    // この選択済みアイテムが選択されたままを維持します。
    event.stopPropagation();

    // ただしこれででは、選択肢のドロップダウンリストが開きっぱなしになるので (マウスク
    // リックイベントの伝達を阻止したため)、
    // 代わりに自前で ESC キー押下を模擬することで、ドロップダウンリストを閉じます。
    const keyEvent = new KeyboardEvent("keydown", { 
      bubbles: true, 
      cancelable: true, 
      key: "Escape", code: "Escape" });
    event.target.dispatchEvent(keyEvent);
  };

  // コンボボックスのアイテム要素を生成する JavaScript を "comboItemTemplate" の
  // スクリプト名で登録します。
  igRegisterScript("comboItemTemplate", (context) => {

    // まずは普通にコンボボックスのアイテム要素を作成します。
    // なお、このサンプルプログラムでは、"Name" というプロパティを表示に使っています。
    // 適宜ご自身のプログラムに合せて参照するプロパティ名を変更してください。
    const contentElement = document.createElement("div");
    contentElement.textContent = context.item.Name;

    // さらに加えて、このコンボボックスアイテムのクリックイベントを捕捉するための、コンボ
    // ボックスアイテム全面を覆うマスク要素を作成し、クリックイベントハンドラを登録します。
    const maskElement = document.createElement("div");
    maskElement.style.position = "absolute";
    maskElement.style.inset = 0;
    maskElement.addEventListener("click", comboItemClickHandler, true);

    // このように作成した要素 x 2つを配列にして返します。
    return [contentElement, maskElement];
  }, false);
})();

一点、上記 JavaScript プログラム中にて、IgbCombo の DisplayKey に指定するプロパティ名が直接記載されています。上記 JavaScript ファイルを再利用する際は、適宜、表示に参照するプロパティ名を変更・調整するようにしてください。

次にこうしてブラウザに読み込み、登録された JavaScript スクリプト名を、IgbCombo の ItemTemplateScript に指定します。

@*
  IgbCombo の ItemTemplateScrit に、上記 JavaScript コードによって登録されたスクリ
  プトの名前を指定し、コンボボックスのドロップダウンリストに表示するアイテム要素の構築
  をカスタマイズします。
  このカスタマイズによって、アイテム要素のマウスクリックイベントを捕捉し、もしも選択済
  みのアイテムであった場合はクリック処理をキャンセルすることで、選択済みのアイテムをク
  リックしても選択されたままを実現します。
*@
<IgbCombo ... ItemTemplateScript="comboItemTemplate">
</IgbCombo>

こうすることで、IgbCombo のドロップダウンリストに表示されるアイテム要素の DOM 構築が、上記 JavaScript コードによってカスタマイズされ、このカスタマイズによってアイテム要素のマウスクリックイベントを捕捉できるようになり、もしもクリックされたアイテム要素が選択済みアイテムであった場合は、このマウスクリックイベントの伝達を阻止することで、選択済みアイテムを繰り返しクリックしても選択状態が維持されたままとなります。

プログラムコード全体は以下のリンク先からアクセス頂けますので、適宜ご参照ください。

Tagged:

製品について

Ignite UI for Blazor