LoginSignup
7
7

More than 1 year has passed since last update.

【Laravel】CRUDで非同期(Ajax)削除処理を作る

Last updated at Posted at 2022-11-16

Laravelで削除の非同期処理を実装する条件

  1. jQueryを動かすためのCDN
  2. POST通信をするためのトークン【とても重要】
  3. HTMLタグから情報を取得するカスタムデータ属性
  4. コントローラへ非同期通信するためのAjax
  5. コントローラーへ移動するルーティング
  6. データを受取りレコードを削除するコントローラー

スクリーンショット 2022-11-16 13.17.54.png
以下の説明では、非同期で削除するコード以外は省いています。

jQueryを動かすためのCDN

非同期処理(ajax通信)を実装するためにはjQueryの$.ajaxメソッドが必要です
そのためjQueryを動かすためにCDNをHTMLのheadタグに記述します

app.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>@yield('title')</title>

    <!--Bootstrap CSS -->
    {{--<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">--}}
    <link rel="stylesheet" href="{{ asset('css/app.css') }}">

    <!--Font Awesome5-->
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
    <script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
    <meta name="csrf-token" content="{{ csrf_token() }}">
</head>
<body class="d-flex flex-column">

<!-- ヘッダー -->
@include('layouts.header')

<!-- コンテンツ -->
@yield('content')



</body>

<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" ></script>
</body>
</html>

CDNのリンク記述場所に注意

CDNのリンクは、jQueryの処理コード部分よりも
前に記述する必要があります。
後に記述された場合、jQueryが利用できません。
そのため、HTMLのheadタグ内部に記述することが推奨されます。

CDNでの導入方法

https://code.jquery.com にアクセスし
jQuery Core 3.*.*minifiedをクリック
表示されたscriptのコードをコピーしHTMLへ貼り付けします

スクリーンショット 2022-11-16 13.24.14.png

POST通信をするためのトークン【とても重要】

LaravelでPOST通信をするには必ずトークンを送るための記述が必要です
Laravelの仕様でトークンを送らなければエラーが発生し、
通信が失敗、つまりエラーが発生します。

ajaxでトークンを送信する方法とは?

ajaxのコードを処理を記述するscriptタグへ
非同期処理とセットで以下の記述をすることにより
トークンが送信されます

index.blade.php
<script>

// ここからトークン送信処理
$.ajaxSetup({
    headers: {
                'X-CSRF-TOKEN': '{{ csrf_token() }}'
                }
            });

//ここから非同期処理の記述

// $(function() {
//     $.ajax({
//                  type: 'POST'
//                      , url: '/destroy/'+userID
//                      , dataType: 'json'
//                      , data: {'id':userID},
    
    
                

ajaxの場合はページを更新しないためエラーコードが出ず
問題には非常に気が付きにくいことが挙げられます

HTMLタグから情報を取得するカスタムデータ属性

削除の対象になるHTMLタグにカスタムデータ属性

jQuery側にてHTMLのを取得することができます

カスタムデータ属性とは?

htmlタグに付与できるclass属性やid属性などと同じ利用方法の属性で
かつ、オリジナルの名前で設定できる属性です

カスタムデータ属性は、data-***で作成します。
***の部分を任意の文字列で設定できます。
他の要素名(class名、ID名など)とは重複できません。

index.blade.php
 <form  class="id">
        <input data-user_id="{{$user->id}}" type="submit" class="btn-dell" value="削除">
 </form>

削除したいレコードの"ID"をjQueryへ渡すには?

まずはMVCの流れで
コントローラーでモデル(データベース)の情報を取得します

前提条件

  • Laravelのプロジェクトへすでにモデル、コントローラー、ビューファイルが存在する
  • プロジェクトとMySQLなどはすでに紐付けの設定がされている
User.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Users extends Model
{
    
}


HomeController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Users;
use Illuminate\Support\Facades\DB;

class HomeController extends Controller
{
     
    public function index(Request $request)
    {
             
        /* テーブルから全てのレコードを取得する */
        $users = Users::query();
        
         /* ページネーション */
        /* レコード数が多い時にページを分割して表示します(今回は5レコードごとにページを分けます) */
        /* 分割の必要がなければ省略しても問題ありません */
        $posts = $users->paginate(5);

        return view('crud.index', ['posts' => $posts]);
        /* ページネーションが必要なければ、postsはusersに置き換えます */
    }

}

index.blade.php

@extends('layouts.app')

@section('content')

<div class="wrapper mx-auto" style="padding-top:30px;">



<!--テーブル-->

      <div class="table-responsive">
          <table class="table" style="width: 1000px; max-width: 0 auto;">
                <tr class="table-info">
                <th scope="col" >id</th>
                <th scope="col" >名前</th>
             
                  <th scope="col" >削除</th>
                </tr>

<!--繰り返し処理-->
<!--1レコードずつ情報を表示します-->
 @foreach($posts as $user)  
<tr>
 
         <td>{{$user->id}}</td>
         <td>{{$user->name}}</td>

<!-- blade.php内で変数を利用するためには前後を {{ }} で囲む必要があります -->            

<!--削除に必要なボタン要素-->
  <td>  
    <form  class="id">
        <input data-user_id="{{$companie->id}}" type="submit" class="btn btn-danger btn-dell" value="削除">
      </form>
  </td>

</tr>
@endforeach

         </table>
       </div>
    <!--ページネーションを表示する変数-->
       {{ $posts->links() }}

    </div>

コントローラへ非同期通信するためのAjax

index.blade.php

<script type="text/javascript">

// トークンを送信する記述
// Laravelでは通信をする際にトークンを送らなければ仕様でエラーが発生する
$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': '{{ csrf_token() }}'
    }
});


// ここから非同期処理の記述
$(function() {
                
 //削除ボタンに"btn-danger"クラスを設定しているため、ボタンが押された場合に開始されます
              $('.btn-danger').on('click', function() {
                var deleteConfirm = confirm('削除してよろしいでしょうか?');
// メッセージをOKした時(true)の場合、次に進みます 
                    if(deleteConfirm == true) {
                      var clickEle = $(this)
//$(this)は自身(今回は押されたボタンのinputタグ)を参照します
// "clickEle"に対して、inputタグの設定が全て代入されます

                      var userID = clickEle.attr('data-user_id');
 //attr()」は、HTML要素の属性を取得したり設定することができるメソッドです
 //今回はinputタグの"data-user_id"という属性の値を取得します
 //"data-user_id"にはレコードの"id"が設定されているので
 // 削除するレコードを指定するためのidの値をここで取得します

 // .ajaxメソッドでルーティングを通じて、コントローラへ非同期通信を行います。
//見本ではレコードを削除するコントローラへ通信を送るためにはweb.phpを参照すると
//通信方法は"post"に設定し、URL(送信先)を'/destroy/{id}'にする必要があります
                         
              $.ajax({
                 type: 'POST',
                 url: '/destroy/'+userID, //userID にはレコードのIDが代入されています
                 dataType: 'json',
                 data: {'id':userID},
                          })
//”削除しても良いですか”のメッセージで”いいえ”を選択すると次に進み処理がキャンセルされます
            } else {
                    (function(e) {
                      e.preventDefault()
                    });
            };
      });
});
//.ajaxメソッドではオプション(引数)を設定することで送信先(URL)や送信する変数を指定できます
//type は 通信方式をGETもしくはPOSTから選択できます(デフォルトはGETです)
//urlは送信先(URL)を指定します。ルーティングで設定しているURLになるよう文字列と変数を記述します
//dataType はjavascriptからこれから送るデータの種類は何であるかを示します
//json とは "JavaScript Object Notationの略"
//json は javascriptのほかphpや多数の言語でも読み取れるフォーマットなので設定しておけばエラーが出ません

//data はURL先(コントローラー)に渡す値です。今回は削除したいレコードの”id”を渡します。
//dataの書き方は   
//data:{'コントローラーのアクションで使う引数':jQueryから渡す変数}になります
</script>

コントローラーへ移動するルーティング

ajaxで指定するURLはルーティングを参照します。
レコードを削除するコントローラーのアクションにつながるURLは
post/destroy/{id}となっているため、ajaxメソッドでの送信先は
/destroy/ + (idの値が代入されている)変数となります

web.php

Auth::routes();

Route::get('/', 'HomeController@index')->name('crud.index'); /* 一覧表示 */

Route::post('/destroy/{id}', 'HomeController@destroy'); /* レコード削除 */

データを受取りレコードを削除するコントローラー

HomeController.php
public function destroy(Request $request, Users $users) {

//ajaxメソッドから送信されたデータは$requestに格納されます
//ajas側で送信したデータの名前は"id"という名前に設定しているため
//コントローラーで使うには $request->id で出力します
     
            $users = Users::findOrFail($request->id);
//データベースのUsersテーブルから()で指定されたiDのレコードを代入します
            $users->delete();
//usersに代入されているレコード(行)を削除します

    }
7
7
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
7
7