カテゴリーを SELECT で検索するフォームを作るには


カテゴリーリストモジュール( Category_List )を利用して、検索フォームを作る実装について書いてみます。カテゴリーリストモジュールは、子カテゴリーがあった際に入れ子で表示ができるようにするために少し複雑な動きをしています。

まずは、カテゴリーリストモジュールのスニペットを確認してみます。

カテゴリーリストモジュールのスニペット

<!-- BEGIN_MODULE Category_List -->
<div class="acms-margin-bottom-medium">
@include("/admin/module/setting.html")
  <!-- BEGIN category:loop --><!-- BEGIN ul#front -->
  <ul class="acms-list-group">
  <!-- END ul#front --><!-- BEGIN li#front -->
    <li><!-- END li#front --><!-- BEGIN category:veil -->
      <a href="{url}" class="acms-list-group-item">{name}<!-- BEGIN amount:veil -->
        <span class="acms-badge acms-float-right">{amount}</span><!-- END amount:veil -->
      </a><!-- END category:veil --><!-- BEGIN li#rear -->
    </li><!-- END li#rear --><!-- BEGIN ul#rear -->
  </ul>
  <!-- END ul#rear --><!-- END category:loop -->
</div>
<!-- END_MODULE Category_List -->

エントリーリストモジュール であれば、<ul> は entry:loop の外にあるのが一般的ですが、カテゴリーリストモジュール は、category:loop の内側に <ul> があるのでカスタマイズする際には注意が必要です。

最終的な表示されるフォームのHTML

上記のようなスニペットを利用して、以下のような HTML ができるようなことを考えてみます。

<form action="" method="POST">
  <select name="cid">
    <option>全て</option>
    <option value="2">お知らせ</option>
    <option value="3">製品情報</option>
    <option value="4">会社概要</option>
    <option value="6">お問い合わせ</option>
    <option value="7">採用情報</option>
    <option value="8">物件情報</option>
  </select>
  <input type="submit" name="ACMS_POST_2GET" value="検索">
</form>

フォームとしては実際には、以下のようになります。

スニペットを改造してみる

普通に考えると、まずは以下のように実装するのではないかと思います。

<form action="" method="POST">
  <!-- BEGIN_MODULE Category_List -->
  <select name="cid">
    <option value="">全て</option>
  <!-- BEGIN category:loop -->
    <option value="{cid}">{name}</option>
  <!-- END category:loop -->
  </select>
  <!-- END_MODULE Category_List -->
<input type="submit" name="ACMS_POST_2GET" value="検索">
</form>

しかし、これを a-blog cms のテンプレートに書くと、残念ながら以下のような結果になります。今回、どうしてそうなるのかという説明は省きますが、必要のない   <option value=""></option> を表示させないようにすることを追記することを考えます。

<select name="cid">
  <option value="">全て</option>
  <option value=""></option>
  <option value="2">お知らせ</option>
  <option value=""></option>
  <option value="3">製品情報</option>
  <option value=""></option>
  <option value="1">家庭用製品</option>
  <option value=""></option>
  <option value="5">業務用製品</option>
  <option value=""></option>
  <option value=""></option>
  <option value=""></option>
  <option value="4">会社概要</option>
  <option value=""></option>
  <option value="6">お問い合わせ</option>
  <option value=""></option>
  <option value="7">採用情報</option>
  <option value=""></option>
  <option value="8">物件情報</option>
  <option value=""></option>
  <option value=""></option>
</select>

空の optoin を非表示にする

方法としては IFブロックを利用して表示されて欲しくない部分は出ないようにします。例えば、{cid} が空ではない時という条件を設定したり

  <!-- BEGIN category:loop -->
    <!-- BEGIN_IF [{cid}/nem]-->
      <option value="{cid}">{name}</option>
    <!-- END_IF -->
  <!-- END category:loop -->

子カテゴリーがあるものがあった時に子カテゴリーを非表示にしたい場合を考え、階層の変数 {level} が 1 のものだけを表示する

  <!-- BEGIN category:loop -->
    <!-- BEGIN_IF [{level}/eq/1]-->
      <option value="{cid}">{name}</option>
    <!-- END_IF -->
  <!-- END category:loop -->

このような設定をします。

selected="selected" の処理

検索結果のページで select が選択したところが選択したままになるようにするためには、option に selected="selected" をつける必要があります。

今回は、option の中に IFブロックを書き、グローバル変数 %{CID} とカテゴリーリストモジュール内の {cid} との比較を行います。

<!-- BEGIN_IF [%{CID}/eq/{cid}] --> selected="selected"<!-- END_IF -->

最終的なカテゴリーリストモジュールの実装

  1. スニペットを改造してみる
  2. 空の optoin を非表示にする
  3. selected="selected" の処理

を実装し、人が読みやすいようにテンプレートを書くと以下のようになります。

<form action="" method="POST">
  <!-- BEGIN_MODULE Category_List -->
  <select name="cid">
    <option value="">全て</option>
  <!-- BEGIN category:loop -->
    <!-- BEGIN_IF [{level}/eq/1]-->
    <option value="{cid}"
      <!-- BEGIN_IF [%{CID}/eq/{cid}] -->
        selected="selected"
      <!-- END_IF -->
    >{name}</option>
    <!-- END_IF -->
  <!-- END category:loop -->
  </select>
  <!-- END_MODULE Category_List -->
<input type="submit" name="ACMS_POST_2GET" value="検索">
</form>

a-blog cms のテンプレートは、必要がないところは消える仕様になっていますが、消える部分の外にある改行だけ有効になってしまうことから上記を実行すると

<form action="" method="POST">
  
  <select name="cid">
    <option value="">全て</option>
  
    
  
    
    <option value="2"
      
    >お知らせ</option>
    
  
    
  
    
    <option value="3"
      
    >製品情報</option>


(以下略)

のように空白だらけのソースコードになります。HTML として表側では改行や空白は関係ないので、このままでも構いませんが綺麗にした例もご紹介しておきます。

<form action="" method="POST">
  <!-- BEGIN_MODULE Category_List -->
  <select name="cid">
    <option value="">全て</option>
  <!-- BEGIN category:loop --><!-- BEGIN_IF [{level}/eq/1]-->  <option value="{cid}"<!-- BEGIN_IF [%{CID}/eq/{cid}] --> selected="selected"<!-- END_IF -->>{name}</option>
  <!-- END_IF --><!-- END category:loop --></select>
  <!-- END_MODULE Category_List -->
<input type="submit" name="ACMS_POST_2GET" value="検索">
</form>

この HTML であれば、以下のようなソースコードになります。

<form action="" method="POST">
  
  <select name="cid">
    <option value="">全て</option>
    <option value="2">お知らせ</option>
    <option value="3">製品情報</option>
    <option value="4">会社概要</option>
    <option value="6">お問い合わせ</option>
    <option value="7" selected="selected">採用情報</option>
    <option value="8">物件情報</option>
  </select>
  
<input type="submit" name="ACMS_POST_2GET" value="検索">
</form>

今回は、特殊なカテゴリーリストのループをシンプルにする方法と、現在表示している selected の対応についての紹介でした。

同じタグ付けがされている記事