htmxでinput/datalistを使ってワード検索後、選択された要素をAPIに飛ばしたい

執筆日: 更新日:
この記事の目次
chevron_right PHP
chevron_right HTML

一つの要素に複数のtriggerを貼る場合などにも使えます。

datalistタグはいわゆるComboBoxで、文字を入力することもできるドロップダウンリストです。
入力された文字をAPIで検索して絞り込んで、選択されたらまたAPIに投げたい、みたいな事があると思います。

このとき、HTMLではinputdatalistを使ってこれを実現しますが、それをHTMXでやる方法を調べたので記します。

PHP

ワードを検索するAPI(search.php)

とりあえずサンプルで、フォネティックリストを検索するとします。
検索は大文字小文字を区別します。

<?php
$phoneticList = [
    'Alpha',
    'Bravo',
    'Charlie',
    'Delta',
    'Echo',
    'Foxtrot',
    'Golf',
    'Hotel',
    'India',
    'Juliet',
    'Kilo',
    'Lima',
    'Mike',
    'November',
    'Oscar',
    'Papa',
    'Quebec',
    'Romeo',
    'Sierra',
    'Tango',
    'Uniform',
    'Victor',
    'Whiskey',
    'X-ray',
    'Yankee',
    'Zulu'
];

$searchVal = $_GET['searchVal'];

foreach ($phoneticList as $word) {
    if (empty($searchVal) || str_contains($word, $searchVal)) {
        echo '<option value="' . $word . '"></option>';
    }
}

検索結果を表示するAPI(show.php)

datalistで値が選択されたら呼び出されるAPIです。
選択された値を表示します

<?php
$word = $_GET['searchVal'];

// サンプル
// XSSとか考慮する必要あり
echo '<script>alert("' . $word . 'が選択されました")</script>';

HTML

サンプルとしてこんな感じです。
キモとしてはfrom:#search_boxのようにID要素を指定して、複数のtriggerを貼ることです

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HTMX検索テスト</title>
</head>
<body>
    <!-- ダミー要素。ここでinputに入力された値を検知してAPIに投げる -->
    <div
        hx-target="#word_list"
        hx-trigger="keyup from:#search_box delay:25ms"
        hx-get="search.php"
        hx-include="#search_box"
    >
    </div>

    <!-- ダミー要素。選択された値を表示するAPIに投げる -->
    <!-- hx-includeが「#search_box」なのは、datalistで選択された値をinputが持っているから。list要素でつながっている -->
    <div
        hx-target="#result"
        hx-trigger="change from:#search_box"
        hx-get="show.php"
        hx-include="#search_box"
    >
    </div>

    <!-- ワード検索のinput要素と、検索結果の一覧を表示するdatalist要素 -->
    <input
        id="search_box"
        list="word_list"
        name="searchVal"
    />
    <datalist
        id="word_list"
    ></datalist>

    <div id="result"></div>

    <script src="https://unpkg.com/htmx.org@2.0.2" integrity="sha384-Y7hw+L/jvKeWIRRkqWYfPcvVxHzVzn5REgzbawhxAuQGwX1XWe70vji+VSeHOThJ" crossorigin="anonymous"></script>
</body>
</html>

実行して遊んでみてください。

[PR] おすすめの本
この記事を書いた人
Nな人(えぬなひと)。
Nは本名から取っています。
Laravelが大好きなPHPerで、WEBを作るときはLaravelを技術スタックに絶対推すマン。
PHP、Pythonと、昔はperlを書いていたP言語エンジニア。
最近はNimを書いたりしています。