Laravelの基本はこちらから学べます

Laravel8で掲示板を作成する③(新規投稿機能)




今回はLivewireを利用して新規投稿機能を作成していきましょう!

こちらは、https://aburasoba.org/laravel8-livewire-index/ の続きになります。

新規作成機能を追加していく。

では、新規投稿機能を作成していきましょう。

まずは、Laravel jetstream が用意している、blade component をインストールします。

% php artisan vendor:publish --tag=jetstream-views

このコマンドで、数多くの blade component を使えるようになります。今回はこちらの中の modal を使用していきます。

resourses/views/livewire/students/create.blade.php

<div>
    <button type="button" class="bg-white hover:bg-gray-100 text-gray-800 font-semibold py-2 px-4 border border-gray-400 rounded shadow" 
        wire:click.prevent="openModal()">新規追加</button>
    <x-jet-modal wire:model="modalStatus">
        <x-slot name="slot">
            <div class="flex justify-between items-center border-b p-2 text-xl">
                <div></div>
                <h6 class="text-xl font-bold">新規追加</h6>
                <button type="button" wire:click.prevent="closeModal()">✖</button>
            </div>
            <div class="p-10">
                <!-- content -->
                <form class="w-full">
                    <div class="md:flex md:items-center mb-6">
                        <div class="md:w-1/3">
                            <label class="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4"
                                for="inline-first-name">
                                名前
                            </label>
                        </div>
                        <div class="md:w-2/3">
                            <input
                                class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-purple-500"
                                id="inline-first-name" type="text" value="" name="firstname" wire:model="firstname">
                                @error('firstname')
                                    <span class="block sm:inline text-red-700">{{ $message }}</span>
                                @enderror
                        </div>
                    </div>
                    <div class="md:flex md:items-center mb-6">
                        <div class="md:w-1/3">
                            <label class="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4"
                                for="inline-last-name">
                                苗字
                            </label>
                        </div>
                        <div class="md:w-2/3">
                            <input
                                class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-purple-500"
                                id="inline-last-name" type="text" placeholder="" name="lastname" wire:model="lastname">
                                @error('lastname')
                                    <span class="block sm:inline text-red-700">{{ $message }}</span>
                                @enderror
                        </div>
                    </div>
                    <div class="md:flex md:items-center mb-6">
                        <div class="md:w-1/3">
                            <label class="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4"
                                for="inline-email">
                                メールアドレス
                            </label>
                        </div>
                        <div class="md:w-2/3">
                            <input
                                class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-purple-500"
                                id="inline-email" type="text" placeholder="" name="email" wire:model="email">
                                @error('email')
                                    <span class="block sm:inline text-red-700">{{ $message }}</span>
                                @enderror
                        </div>
                    </div>
                    <div class="md:flex md:items-center mb-6">
                        <div class="md:w-1/3">
                            <label class="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4"
                                for="inline-phone-number">
                                電話番号
                            </label>
                        </div>
                        <div class="md:w-2/3">
                            <input
                                class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-purple-500"
                                id="inline-phone-number" type="text" placeholder="" name="phone" wire:model="phone">
                                @error('phone')
                                    <span class="block sm:inline text-red-700">{{ $message }}</span>
                                @enderror
                        </div>
                    </div>
                    <div class="flex justify-end">
                        <button
                            class="shadow bg-purple-500 hover:bg-purple-400 focus:shadow-outline focus:outline-none text-white font-bold py-2 px-4 rounded"
                            type="button" wire:click.prevent="store()">
                            追加する
                        </button>
                    </div>
                </form>
            </div>
        </x-slot>
    </x-jet-modal>
</div>

長々と書いていきました。

ここでのポイントはたくさんあります。

livewire component に記載したメソッドを発火させられる。

wire:click.prevent=”openModal()”
wire:click.prevent=”closeModal()”
wire:click.prevent=”store()”


これらのメソッドはまだ未定義ですので、次のセクションで実装していきます。

livewire component に記載したプロパティを意味する。

wire:model=”firstname”
wire:model=”lastname”
wire:model=”email”
wire:model=”phone”

wire:model=”modalStatus”


これらのプロパティに関してもまだ未定義ですので、次のセクションにて実装をしていきます。

Laravel jetstream が用意をした component を使用するためのタグ

<x-jet-modal>
こちらを記入することで、views/vendor/jetstream/components/modal.blade.php を利用することができます。


<x-jet-slot name=”slot”>

views/vendor/jetstream/components/modal.blade.php を確認しましょう。

//省略

<div x-show="show" class="bg-white rounded-lg overflow-hidden shadow-xl transform transition-all sm:w-full {{ $maxWidth }}"
                    x-transition:enter="ease-out duration-300"
                    x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
                    x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
                    x-transition:leave="ease-in duration-200"
                    x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
                    x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95">
        {{ $slot }}
    </div>
</div>

こちらは、modal のコンポーネントになっていますが、
注目する点は {{ $slot }} です。

先ほどの、<x-jet-slot name=”slot”> タグに囲われた部分が、modal 内の {{ $slot }} に代入され表示されます。使いまわせて非常に便利ですね。

新規投稿機能、Livewireにメソッド・プロパティを追記していく

前セクションでは、blade を作成していきました。今セクションではLivewire component にメソッド・プロパティを追加していきましょう。

public $ids;
public $firstname;
public $lastname;
public $email;
public $phone;
public $modalStatus;

    public function openModal() //modalStatusをtrueにしmodalを表示する
    {
        $this->resetInputFields();
        $this->modalStatus = true;
    }

    public function closeModal() //modalStatusをfalseにしmodalを閉じる
    {
        $this->modalStatus = false;
    }
    
    public function resetInputFields() //Inputタグの中身を空にする
    {
        $this->firstname = '';
        $this->lastname = '';
        $this->email = '';
        $this->phone = '';
    }

    public function store() //バリデーションをした後に、生徒のデータを保存
    {
        $validatedData = $this->validate([
            'firstname' => 'required',
            'lastname' => 'required',
            'email' => 'required|email',
            'phone' => 'required',
        ]);

        Student::create($validatedData);
        session()->flash('message', '新規投稿に成功しました。');
        $this->resetInputFields();
        $this->closeModal();
    }

いかがでしょうか。一つ一つのコードを読みながら何をしているのか確認してみてください。

それでは新規投稿機能を動かしていきましょう。
の前に、index.blade.php を修正します。 

resources/views/livewire/students/index.blade.php

<div>
    @if(session()->has('message')) //追加1始まり
        <div class="flex items-center bg-blue-500 text-white text-sm font-bold px-4 py-3" role="alert">
            <svg class="fill-current w-4 h-4 mr-2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M12.432 0c1.34 0 2.01.912 2.01 1.957 0 1.305-1.164 2.512-2.679 2.512-1.269 0-2.009-.75-1.974-1.99C9.789 1.436 10.67 0 12.432 0zM8.309 20c-1.058 0-1.833-.652-1.093-3.524l1.214-5.092c.211-.814.246-1.141 0-1.141-.317 0-1.689.562-2.502 1.117l-.528-.88c2.572-2.186 5.531-3.467 6.801-3.467 1.057 0 1.233 1.273.705 3.23l-1.391 5.352c-.246.945-.141 1.271.106 1.271.317 0 1.357-.392 2.379-1.207l.6.814C12.098 19.02 9.365 20 8.309 20z"/></svg>
            <p>{{ session('message') }}</p>
        </div>
    @endif //追加1ここまで
    <div class="rounded overflow-hidden shadow-lg">
        <div class="px-6 py-4">
            <div class="font-bold text-xl mb-2">All Student</div>
            @include('livewire.students.create') //追加2
        </div>
        <div class="px-6 pt-4 pb-2">
            <table class="table-auto w-full">
                <thead>
                    <tr>
                        <th class="px-4 py-2">First Name</th>
                        <th class="px-4 py-2">Last Name</th>
                        <th class="px-4 py-2">Email</th>
                        <th class="px-4 py-2">Phone</th>
                        <th></th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    @foreach ($students as $student)
                        <tr>
                            <td class="border px-4 py-2">{{ $student->firstname }}</td>
                            <td class="border px-4 py-2">{{ $student->lastname }}</td>
                            <td class="border px-4 py-2">{{ $student->email }}</td>
                            <td class="border px-4 py-2">{{ $student->phone }}</td>
                            <td class="border px-4 py-2">編集</td>
                            <td class="border px-4 py-2">削除</td>
                        </tr>
                    @endforeach
                </tbody>
            </table>
        </div>
    </div>
</div>

それではアプリケーションで、新規投稿ができるか確認してみましょう!

今回はここまで!次回は編集、削除機能を作成していきましょう!




コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です