BodyTemplate を使ってセルのレンダリング内容をカスタマイズする

Blazor 向け UI コンポーネント製品 Ignite UI for Blazor が提供するグリッドコンポーネント、IgbGrid について、そのセル内にハイパーリンクを配置したい場合は、セル内のレンダリング内容を完全にカスタマイズできる BodyTemplate を使う方法があります。

IgbGrid コンポーネントのマークアップ内で IgbColumn コンポーネントを使って列を定義する際に、その IgbColumn コンポーネント内に <BodyTemplate> とマークアップすると、その列のセルのレンダリング内容が <BodyTemplate> 内に記述した内容で完全に置き換えられます。

この BodyTtemplate を使うことで、所定の列のセルのレンダリング内容を <a> タグによるハイパーリンクに差し替えることが可能です。以下にコード例を示します。

<IgbGrid Data="_products"
         AutoGenerate="false"
         PrimaryKey="@nameof(Product.Id)">

  <IgbColumn Field="@nameof(Product.Id)" Header="ID" Width="10%" />

  <IgbColumn Field="@nameof(Product.Name)" Header="製品名" Width="30%" />

  <IgbColumn Field="@nameof(Product.URL)" Header="製品紹介ページ" Width="60%">
    <BodyTemplate>
      <a href="@context.Cell.Value" target="_blank">
        @context.Cell.Value
      </a>
    </BodyTemplate>
  </IgbColumn>

</IgbGrid>

@code
{
  private record Product(int Id, string Name, string URL);

  private readonly IEnumerable<Product> _products = [
    new(1, "Ignite UI for Blazor", 
      "https://jp.infragistics.com/products/ignite-ui-blazor"),
    new(2, "Ignite UI for Angular", 
      "https://jp.infragistics.com/products/ignite-ui-angular"),
    new(3, "Ignite UI for React", 
      "https://jp.infragistics.com/products/ignite-ui-react"),
    new(4, "Ignite UI for Web Components", 
      "https://jp.infragistics.com/products/ignite-ui-web-components"),
  ];
}

上記コード例の実行例は以下のようになります。

上記コード内で出てくる “context” などについて詳しくは、以下のナレッジベース記事が参考になります。下記をご参照いただきますと、上記コード例において、リンク先は Product.URL を使用しつつ、表示テキストは Product.Name を使用する、といったことも可能です。

IgbGrid – セルのテンプレート内から、該当する行データや、同行の任意の列値を参照する方法 – INFRAGISTICS ナレッジ ベース

より高いパフォーマンスが求められる場合

なお、データ件数や Blazor WebAssembly か Blazor Serevr かの違いなどによって、<BodyTemplate> を使用した場合に、表示速度が重くなる場合があるかもしれません。その場合は、残念ながら C# だけでは完結しないものの、JavaScript による実装とすることで処理性能を引き上げることが可能です。

具体的には <BodyTempate> は使わずに、IgbColumn の BodyTemplateScript に、”igRegisterScript” JavaScript 関数に登録したスクリプト名を指定することで実現します。以下に例を示します。

まず以下のように、セル内容の DOM オブジェクトを返す関数を定義して、Ignite UI for Blazor によって提供される igRegisterScript 関数に、登録名を添えて登録します。igRegisterScript 関数について詳しくは、下記リンク先のナレッジベース記事を参照ください。

Ignite UI for Blazor – igRegisterScript, igRemoveScript の使い方 – INFRAGISTICS ナレッジ ベース

セル内容を返す関数には、その引数にコンテキストが渡されますので、その引数に渡されたコンテキスト変数をたどると、行データまで参照可能となっており、これら情報をもとに a 要素を構築して、この関数から返すようにします。

/* wwwroot/script.js */
igRegisterScript("urlColumnTemplate", (context) => {

  // 引数 context には、セルの情報が格納されており、行データまで参照可能です。
  const productName = context.cell.row.data.Name;
  const productUrl = context.cell.row.data.URL;

  // セル内に表示する DOM 要素を生成して返却します。
  const a = document.createElement("a");
  a.textContent = productName;
  a.href = productUrl;
  return a;

}, false)

こうして作成した JavaScript ファイルを、フォールバックページ (Blazor WebAssembly であれば wwwroot/index.html) 内に script タグで読み込んでおきます。

<!DOCTYPE html>
<html lang="en">
    ...
    <script src="_content/IgniteUI.Blazor/app.bundle.js"></script>
    <script src="script.js"></script>
    <script src="_framework/blazor.webassembly.js"></script>
</body>
</html>

あとは、IgbColumn コンポーネントにて、BodyTemplateScript パラメーターに、先の JavaScript にて igRegisterScript 関数に指定した名前を指定します。

<IgbGrid ...>
  ...
  <IgbColumn Field="@nameof(Product.URL)" Header="製品紹介ページ" Width="60%"
             BodyTemplateScript="urlColumnTemplate" />

</IgbGrid>

以上で下図のように、JavaScript によるセルのレンダリング内容のカスタマイズが実現します。

なお、上記実装例における JavaScript では、ブラウザの DOM API を直に使って、セル内の表示要素を構築していましたが、Ignite UI for Blazor に付属の HTML テンプレート機能 (igTemplating) を使って、以下のようにも実装可能です。

/* wwwroot/script.js */
igRegisterScript("urlColumnTemplate", (context) => {

  const productName = context.cell.row.data.Name;
  const productUrl = context.cell.row.data.URL;

  return igTemplating.html`<a href="${productUrl}">${productName}</a>`;
}, false)

上記コードにある igTemplating について詳しくは、下記リンク先のナレッジベース記事を参照ください。

Ignite UI for Blazor – igTemplating の使い方 – INFRAGISTICS ナレッジ ベース

以上のサンプルプログラム全体は以下のリンク先から入手・アクセス頂けます。

Tagged:

製品について

Ignite UI for Blazor