Open7

[laravel][Inertia]顧客検索機能

ShiroshitaShiroshita

🫠条件

カナ または 電話番号 前方一致

  • 入力されている場合
    • 検索ヒットした場合:結果を表示
    • 検索ヒットしない場合:全件表示
  • 入力されていない場合:全件表示
ShiroshitaShiroshita

👽Index.vue

resources\js\Pages\Customers\Index.vue
<script setup>
import FlashMessage from "@/Components/FlashMessage.vue";
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout.vue";
import { Head, Link } from "@inertiajs/vue3";
import Pagination from "@/Components/Pagination.vue";
import { ref } from "vue";
import { Inertia } from "@inertiajs/inertia";

// コントローラーから受け取る場合は「defineProps」
defineProps({
    customers: Object,
});

const search = ref("");
// ref の値を取得するには .valueが必要
const searchCustomers = () => {
    Inertia.get(route("customers.index", { search: search.value }));
};
</script>

<template>
    <Head title="顧客一覧" />

    <AuthenticatedLayout>
        <template #header>
            <h2 class="font-semibold text-xl text-gray-800 leading-tight">顧客一覧</h2>
        </template>

        <div class="py-12">
            <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
                <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                    <div class="p-6 text-gray-900">
                        <section class="text-gray-600 body-font">
                            <div class="container px-5 py-8 mx-auto">
                                <FlashMessage />
                                <div class="flex pl-4 mt-4 lg:w-2/3 w-full mx-auto">
                                    <div>
                                        <input
                                        class="px-4 py-3 mb-4 title-font tracking-wider font-medium text-gray-900 text-sm bg-gray-100 rounded"
                                            type="text"
                                            name="search"
                                            v-model="search"
                                            placeholder="カナ・電話番号"

                                        />
                                        <button
                                            class="bg-green-500 text-white py-3 px-4 mb-4 border-0 rounded"
                                            @click="searchCustomers"
                                        >
                                            検索
                                        </button>
                                    </div>
                                    <Link
                                        as="button"
                                        :href="route('customers.create')"
                                        class="flex ml-auto text-white bg-green-500 border-0 py-2 px-6 mb-4 focus:outline-none hover:bg-green-600 rounded"
                                        >顧客登録</Link
                                    >
                                </div>
                                <div class="lg:w-2/3 w-full mx-auto overflow-auto">
                                    <table
                                        class="table-auto w-full text-left whitespace-no-wrap"
                                    >
                                        <thead>
                                            <tr>
                                                <th
                                                    class="px-4 py-3 title-font tracking-wider font-medium text-gray-900 text-sm bg-gray-100 rounded-tl rounded-bl"
                                                >
                                                    ID
                                                </th>
                                                <th
                                                    class="px-4 py-3 title-font tracking-wider font-medium text-gray-900 text-sm bg-gray-100"
                                                >
                                                    氏名
                                                </th>
                                                <th
                                                    class="px-4 py-3 title-font tracking-wider font-medium text-gray-900 text-sm bg-gray-100"
                                                >
                                                    カナ
                                                </th>
                                                <th
                                                    class="px-4 py-3 title-font tracking-wider font-medium text-gray-900 text-sm bg-gray-100"
                                                >
                                                    電話番号
                                                </th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            <tr
                                                v-for="customer in customers.data"
                                                :key="customer.id"
                                            >
                                                <td
                                                    class="border-b-2 border-gray-200 px-4 py-3"
                                                >
                                                    {{ customer.id }}
                                                </td>

                                                <td
                                                    class="border-b-2 border-gray-200 px-4 py-3"
                                                >
                                                    {{ customer.name }}
                                                </td>
                                                <td
                                                    class="border-b-2 border-gray-200 px-4 py-3"
                                                >
                                                    {{ customer.kana }}
                                                </td>
                                                <td
                                                    class="border-b-2 border-gray-200 px-4 py-3"
                                                >
                                                    {{ customer.tel }}
                                                </td>
                                            </tr>
                                        </tbody>
                                    </table>
                                </div>
                            </div>
                            <Pagination
                                class="mt-6"
                                :links="customers.links"
                            ></Pagination>
                        </section>
                    </div>
                </div>
            </div>
        </div>
    </AuthenticatedLayout>
</template>

ShiroshitaShiroshita

🐘CustomerController

Gitの作成元ブランチを間違えてファイルが消えたと勘違いし焦ったのはここだけの話

ページネーションに加え、検索結果をだせるように編集

app\Http\Controllers\CustomerController.php
<?php

namespace App\Http\Controllers;

use App\Models\Customer;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreCustomerRequest;
use App\Http\Requests\UpdateCustomerRequest;
use Inertia\Inertia;
use Illuminate\Http\Request;

class CustomerController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        // $getTest = Customer::select('id','name','kana','tel')->get();
        // $getPaginate = Customer::select('id','name','kana','tel')->paginate(50);
        // dd($getTest,$getPaginate);

        $customers = Customer::SearchCustomers($request->search)->select('id','name','kana','tel')->paginate(50);
        // dd($customers);
        return Inertia::render('Customers/Index',[
            'customers' => $customers
        ]);
        
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \App\Http\Requests\StoreCustomerRequest  $request
     * @return \Illuminate\Http\Response
     */
    public function store(StoreCustomerRequest $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Customer  $customer
     * @return \Illuminate\Http\Response
     */
    public function show(Customer $customer)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Customer  $customer
     * @return \Illuminate\Http\Response
     */
    public function edit(Customer $customer)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \App\Http\Requests\UpdateCustomerRequest  $request
     * @param  \App\Models\Customer  $customer
     * @return \Illuminate\Http\Response
     */
    public function update(UpdateCustomerRequest $request, Customer $customer)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Customer  $customer
     * @return \Illuminate\Http\Response
     */
    public function destroy(Customer $customer)
    {
        //
    }
}

ShiroshitaShiroshita

🐘Customer.php

app\Models\Customer.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Customer extends Model
{
    use HasFactory;

    // 顧客検索機能
    public function scopeSearchCustomers($query, $input = null)
    {
        if (!empty($input)) {
            if (Customer::where('kana', 'like', $input . '%')
                ->orWhere('tel', 'like', $input . '%')->exists()
            ) {
                return $query->where('kana', 'like', $input . '%')
                    ->orWhere('tel', 'like', $input . '%');
            }
        }
    }
}