【Laravel Prompts】使い方(search/multisearch)

Laravel

Laravel11の公式パッケージ Prompts の使い方の記録と解説の第4回です。

Laravel - The PHP Framework For Web Artisans
Laravel is a PHP web application framework with expressive, elegant syntax. We’ve already laid the foundation — freeing ...

前回はピュアPHPでpause、info、table、spin、progressを実装しました。

今回はピュアPHPでsearch、multisearchを実装していきます。

searchの使い方

searchは検索窓で入力した文字列を基に、

データからリアルタイム検索を行い、

検索結果を選択肢として単一選択させるプロンプトです。

▼PHPコード(src/search.php)

<?php

require_once(__DIR__ . '/../vendor/autoload.php');

use App\Models\User;

use function Laravel\Prompts\search;

$users = [
    ['id' => 1, 'name' => '武田 信玄', 'email' => 'takeda@example.com', 'recess' => true],
    ['id' => 2, 'name' => '上杉 謙信', 'email' => 'uesugi@example.com', 'recess' => false],
    ['id' => 3, 'name' => '北条 氏康', 'email' => 'hojo@example.com', 'recess' => false],
    ['id' => 4, 'name' => '今川 義元', 'email' => 'imagawa@example.com', 'recess' => true],
    ['id' => 5, 'name' => '徳川 家康', 'email' => 'tokugawa@example.com', 'recess' => false],
    ['id' => 6, 'name' => '織田 信長', 'email' => 'oda@example.com', 'recess' => false],
    ['id' => 7, 'name' => '斉藤 道三', 'email' => 'saito@example.com', 'recess' => true],
    ['id' => 8, 'name' => '北畠 具教', 'email' => 'kitabatake@example.com', 'recess' => false],
    ['id' => 9, 'name' => '浅井 長政', 'email' => 'asai@example.com', 'recess' => true],
    ['id' => 10, 'name' => '朝倉 義景', 'email' => 'asakura@example.com', 'recess' => true],
];

$f = function ($value) use ($users) {
    $list = [];
    foreach (array_filter($users, fn ($u) => str_contains($u['name'], $value)) as $user) {
        $list[$user['id']] = $user['name'];
    }
    return $list;
};

$selected = search(
    label: 'ユーザー名から検索します。',
    placeholder: '足利 義輝',
    options: fn (string $value) => mb_strlen($value) > 0
        ? $f($value)
        : [],
    hint: '検索したユーザー一覧から選択できます。',
    scroll: 6,
);

var_dump($selected);

「options:」に渡す値は、キーがユーザーID、値が

ユーザー名の配列にしています。

配列インデックスが代入値、値が表示値になっています。

▼実行結果

ユーザー名の検索窓が表示されました。

全角スペースを入力してみます。

検索窓の下にリアルタイム検索結果が表示されました。

矢印キー上下[↑][↓]で選択、[Enter]で確定です。

検索ワードを「信」に変更してみます。

適当に選択して[Enter]で確定します。

選択したユーザーの id が$selectedに格納されました。

▼バリデーション

$selected = search(
    label: 'ユーザー名から検索します。',
    placeholder: '足利 義輝',
    options: fn (string $value) => mb_strlen($value) > 0
        ? $f($value)
        : [],
    hint: '検索したユーザー一覧から選択できます。',
    scroll: 6,
    validate: function (int $id) use ($users) {
        $user = array_slice(array_filter($users, fn ($u) => $u['id'] === $id), 0, 1)[0];
        if ($user['recess']) {
            return 'このユーザーは休会中です。';
        }
    }
);

▼実行結果

「武田 信玄」を選択すると、「recess => true」なので

「休会中」として叱られます。

次の「上杉 謙信」を選択すると警告が消えます。

そのまま確定すると処理続行されます。

multisearchの使い方

multisearchは検索窓で入力した文字列を基に、

データからリアルタイム検索を行い、

検索結果を選択肢として複数選択させるプロンプトです。

▼PHPコード(src/multisearch.php)

<?php

require_once(__DIR__ . '/../vendor/autoload.php');

use App\Models\User;

use function Laravel\Prompts\multisearch;

$users = [
    ['id' => 1, 'name' => '武田 信玄', 'email' => 'takeda@example.com', 'recess' => true],
    ['id' => 2, 'name' => '上杉 謙信', 'email' => 'uesugi@example.com', 'recess' => false],
    ['id' => 3, 'name' => '北条 氏康', 'email' => 'hojo@example.com', 'recess' => false],
    ['id' => 4, 'name' => '今川 義元', 'email' => 'imagawa@example.com', 'recess' => true],
    ['id' => 5, 'name' => '徳川 家康', 'email' => 'tokugawa@example.com', 'recess' => false],
    ['id' => 6, 'name' => '織田 信長', 'email' => 'oda@example.com', 'recess' => false],
    ['id' => 7, 'name' => '斉藤 道三', 'email' => 'saito@example.com', 'recess' => true],
    ['id' => 8, 'name' => '北畠 具教', 'email' => 'kitabatake@example.com', 'recess' => false],
    ['id' => 9, 'name' => '浅井 長政', 'email' => 'asai@example.com', 'recess' => true],
    ['id' => 10, 'name' => '朝倉 義景', 'email' => 'asakura@example.com', 'recess' => true],
];

$f = function ($value) use ($users) {
    $list = [];
    foreach (array_filter($users, fn ($u) => str_contains($u['name'], $value)) as $user) {
        $list[$user['id']] = $user['name'];
    }
    return $list;
};

$selected = multisearch(
    label: 'ユーザー名から検索します。',
    placeholder: '足利 義輝',
    options: fn (string $value) => mb_strlen($value) > 0
        ? $f($value)
        : [],
    hint: '検索したユーザー一覧から選択できます。',
    scroll: 6,
    required: '最低限ユーザー1件は選択してください。',
);

var_dump($selected);

▼実行結果

検索窓が表示されました。

全角スペースを入力してみます。

ユーザー一覧がチェックボックス付きで表示されます。

矢印キー上下[↑][↓]で選択肢移動、半角スペースで選択、[Enter]で確定です。

何も選択しないで確定すると叱られます。

適当に選択してみます。

キーワードを「信」に変更してみます。

適当に選択して確定してみます。

検索ワード変更前に選択したものも保持されています。

▼バリデーション

$selected = multisearch(
    label: 'ユーザー名から検索します。',
    placeholder: '足利 義輝',
    options: fn (string $value) => mb_strlen($value) > 0
        ? $f($value)
        : [],
    hint: '検索したユーザー一覧から選択できます。',
    scroll: 6,
    required: '最低限ユーザー1件は選択してください。',
    validate: function (array $ids) use ($users) {
        $recess = array_map(
            fn ($e) => $e['name'],
            array_filter(
                $users,
                fn ($u) => in_array($u['id'], $ids) && $u['recess']
            )
        );
        if ($recess) {
            return 'ユーザー' . implode('、', $recess) . 'は休会中です。';
        }
    }
);

▼実行結果

「recess => true」のユーザーを選択して確定すると叱られます。

今回は以上です。

次回はtextareaをピュアPHPで実装していきます。

コメント

タイトルとURLをコピーしました