0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Laravelでajaxを使ってページ遷移しないでデータベースを更新する

Posted at

Laravelでajax通信をする

写真に添えられたチェックボックスをクリックすることでタグ付けができるアプリを作りました。
元々はLaravelでformをPOSTしていましたが、ajax通信にすることでページ遷移せずにformをPOSTできるようにしたかった。その作業メモです。

1.まずはLaravelにjQueryをインストールする。

1-1. jQueryをインストールする。Laravelのプロジェクトディレクトリにて下記実行。
$ npm install jquery --save
1-2.resources/js/ディレクトリに、適当な.jsファイルを作って中に記述する。

※今回はajaxPost.jsを作った
スクリーンショット 2022-10-04 23.08.27.png
とりあえずちゃんと動作するか確認するために下記のコードを記述

$(function(){
    console.log('run jQuery')
});
1-3.webpack.mix.jsを編集する
const mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js')
    .js('resources/js/ajaxPost.js', 'public/js')  //追加。作成したajaxPost.jsファイルを、public/jsディレクトリにつなげる。
    .autoload( {"jquery": [ '$', 'window.jQuery' ],} ) //追加。jQueryを使えるようにするため
    .vue()
    .sass('resources/sass/app.scss', 'public/css');
1-4.ビルドする
$ npm run dev

public/jsディレクトリにajaxPost.jsが表示される
スクリーンショット 2022-10-04 23.15.37.png

1-5.ちゃんと動くかテストする

作ったjsファイルを読み込みたいBladeファイルにソースを貼る

<script src="{{mix('js/ajaxPost.js')}}"></script>

このBladeファイルを開いたときにコンソールに'run jQuery'と表示されていればちゃんと読み込みできてます。
ここまで出来てれば、LaravelでjQueryが使えるようになったぜ。

2.ajax通信

元々のコード

マイグレーションファイル

create_photos_table.php
    public function up()
    {
        Schema::create('photos', function (Blueprint $table) {
            $table->id();
            $table->string('path');//追記!!!
            $table->dateTime('date')->nullable();//追記
            $table->timestamps();
        });
    }
create_players_table.php
    public function up()
    {
        Schema::create('players', function (Blueprint $table) {
            $table->id();
            $table->string('name_kanji');//追記
            $table->string('name_kana');//追記
            $table->string('nickname');//追記
            $table->integer('number');//追記
            $table->timestamps();
        });
    }

中間テーブル

create_photo_player_table.php
    public function up()
    {
        Schema::create('photo_player', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('photo_id');
            $table->unsignedBigInteger('player_id');
            $table->foreign('photo_id')->references('id')->on('photos')->onDelete('cascade');
            $table->foreign('player_id')->references('id')->on('players')->onDelete('cascade');
            $table->timestamps();
        });
    }

モデル

Photo.php
    public function Players()
    {
        return $this->belongsToMany('App\Models\Player')->withTimestamps();
    }
Player.php
    public function Photos()
    {
        return $this->belongsToMany('App\Models\Photo')->withTimestamps();
    }

ビューファイル

taggingAll.blade.php
                <form class=form id="form" action="{{ route('photo.update',$photo->id)}}" method="POST"> 
                        @csrf
                        @method('PUT')
                    <p>
                        @foreach ($players->sortBy('number')  as $player)
                            <label class="checkbox">
                                <input class="PlayerCheckBox" type="checkbox" name="players[]" value="{{$player->id}}"
                                @if(in_array($player->id , $photo->players->pluck('id')->toArray())) checked @endif> 
                                    <!-- player_idとphotoが持っているplayer_idが一致したらチェック -->
                                {{ $player->number }}{{ $player->nickname }}
                            </label>
                        @endforeach
                    </p>
                </form>

コントローラー

PhotoController.php
    public function update(Request $request, $id)
    {
        $photo = Photo::find($id);
        $photo->players()->sync(request()->players);
        return back()->with('success', '編集完了しました');
    }

jsファイルの記述(ajax通信)

ajaxPost.js
$( function (){

    $('.PlayerCheckBox').on('change', function(){  //checkboxをクリックした時に発動

            // let form = $('#form')  //これだと常に最初のformを指定してしまうのでだめ
            let form = $(this.form);  //クリックしたcheckboxを含むformをjqueryで取得
        
        $.ajax({
            headers: {
            "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
            },

            url     :   form.attr('action'),  //formのaction要素を参照
            type    :   form.attr('method'),  //formのmethod要素を参照
            data    :   form.serialize(),     //formで送信している内容を送る
        })

        //通信が成功した時
        .done((res)=>{
            //何か処理
        })
        //通信が失敗したとき
        .fail((error)=>{
            //何か処理
        })
    })
});
↑のコードを書いた上でビルドする
$ npm run dev

public/js/ajaxPost.jsの内容が更新されていればビルドできている証拠

ビューファイルでの読み込み

taggingAll.blade.php
<script src="{{asset('js/ajaxPost.js')}}"></script>
もしくは
<script src="{{mix('js/ajaxPost.js')}}"></script>

これを忘れているとせっかく書いたajax通信の記述が使われないのでお忘れなく。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?