ichihhd
@ichihhd

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

一覧表示、検索機能を非同期処理(ajax)を用いて行いたい

解決したいこと

商品管理ツールを作成しているのですが、一覧表示、検索機能において非同期処理を用いて行いたいです。
自分なりに調べてapp.blade.phpにscriptタグを用いて作成したのですがうまく作動いたしません。
エラーなどは特に出ませんが、非同期処理が行われない状況です。
また、何をもってして、非同期処理が作動したのかと判断基準が私の中であいまいなので、そこの点も含めてご教授願います。

該当するソースコード

app.blade.php

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<script src="https://code.jquery.com/jquery-3.7.0.min.js" integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.bunny.net/css?family=Nunito" rel="stylesheet">

    <!-- Scripts -->
    @vite(['resources/sass/app.scss', 'resources/js/app.js'])
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
            <div class="container">
                <a class="navbar-brand" href="{{ url('/') }}">
                    {{ config('app.name', 'Laravel') }}
                </a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <!-- Left Side Of Navbar -->
                    <ul class="navbar-nav me-auto">

                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul class="navbar-nav ms-auto">
                        <!-- Authentication Links -->
                        @guest
                            @if (Route::has('login'))
                                <li class="nav-item">
                                    <a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
                                </li>
                            @endif

                            @if (Route::has('register'))
                                <li class="nav-item">
                                    <a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
                                </li>
                            @endif
                        @else
                            <li class="nav-item dropdown">
                                <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                    {{ Auth::user()->name }}
                                </a>

                                <div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
                                    <a class="dropdown-item" href="{{ route('logout') }}"
                                       onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                        {{ __('Logout') }}
                                    </a>

                                    <form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
                                        @csrf
                                    </form>
                                </div>
                            </li>
                        @endguest
                    </ul>
                </div>
            </div>
        </nav>

        <main class="py-4">
            @yield('content')
        </main>
    </div>

    <script>
        $(".search").click(function(){
      $.ajax({
         type:"GET",
         url:"{{ route('product') }}",
         dataType: 'json',
      })   
      .done(function(json){
         //通信成功で実行される処理
         console.log(json);
      })
      .fail(function(){
         //通信が失敗した時に実行される処理
      })
      .always(function(){
         //通信の成功と失敗に関わらず実行される処理
      });
   });
    </script>
</body>
</html>

product.blade.php

<!-- 商品一覧画面 -->

@extends('layouts.app')

@section('content')

<div class="search">
  <form action="{{ route('product') }}" method="GET">
  @csrf
  <!-- 検索フォーム -->
  <div class="product_name.search">
  <label for="product_name">{{ __('商品名') }}</label>
    <input type="text" name="keyword" id="keyword" >
  </div>  

  <div class="company_name.serch">
  <label for="company_name">{{ __('メーカー') }}<span class="badge badge-danger ml-2">{{ __('必須') }}</span></label>
        <select class="form-control" name="search" id="search">
          <option>{{"メーカーを選択してください"}}</option>
          <option>{{""}}</option>
        @foreach ($companies as $company)
         <option>{{ $company->company_name }}</option>
         @endforeach
        </select>
  </div>

  <div class="price.search">
    <label for="price">{{ __('価格') }}</label>

    <div class="jougen">
    <p>{{ __('上限') }}</p>
    <input type="number" name="jougenprice" id="jougenprice" >
    </div>

    <div class="kagen">
    <p>{{ __('下限') }}</p>
    <input type="number" name="kagenprice" id="kagenprice" >
    </div>

  </div>

  <div class="stock.serach">
  <label for="stock">{{ __('在庫数') }}</label>

    <div class="jougen">
    <p>{{ __('上限') }}</p>
    <input type="number" name="jougenstock" id="jougenstock" >
    </div>

    <div class="kagen">
    <p>{{ __('下限') }}</p>
    <input type="number" name="kagenstock" id="kagenstock" >
    </div>

  </div>
  
  <input type="submit" value="検索" id="kensaku">
  </form>
</div>

<h1>商品一覧</h1>

<table class="table table-striped">
  <thead>
    <tr>
      <th>@sortablelink('id', 'ID')</th>  
      <th>@sortablelink('product_name', '商品名')</th>
      <th>@sortablelink('company_name', 'メーカー')</th>
      <th>@sortablelink('price', '価格')</th>
      <th>@sortablelink('stock', '在庫数')</th>
      <th>@sortablelink('comment', 'コメント')</th>
      <th>画像</th>
      <th>作成日</th>
      <th>更新日</th>
      <th>詳細</th>
      <th>削除</th>
    </tr>
  </thead>
  <tbody>
    @foreach ($products as $product)
    <tr>
      <td>{{ $product->id }}</td>
      <td>{{ $product->product_name }}</td>
      <td>{{ $product->company_name }}</td>
      <td>{{ $product->price }}</td>
      <td>{{ $product->stock }}</td>
      <td>{{ $product->comment }}</td>
      <td>{{ $product->img_path }}</td>
      <td>{{ $product->created_at }}</td>
      <td>{{ $product->updated_at }}</td>
      <td><a href="{{ route('product.detail', ['id'=>$product->id]) }}" class="btn btn-primary">詳細</a></td>
      <td>
        <form action="{{ route('product.destroy', ['id'=>$product->id]) }}" method="POST">
          @csrf
          <button type="submit" class="btn btn-danger" onclick='return confirm("削除しますか?")'>削除</button>
        </form>
      </td>
    </tr>
    @endforeach

    <div>
    
   
   
    </div>

    <button type="button" onclick="location.href='{{ route('product_form') }}'"> 商品登録 </button>
  </tbody>
</table>



@endsection

web.php

// 商品一覧画面表示 検索機能
Route::get('/product', [App\Http\Controllers\ProductController::class, 'showList','search'])->name('product');

productcontroller.php

public function showList(Request $request)
    {
         // 商品一覧画面表示/検索処理

        $keyword = $request->input('keyword');
        $search = $request->input('search');
        $jougenprice = $request->input('jougenprice');
        $kagenprice = $request->input('kagenprice');
        $jougenstock = $request->input('jougenstock');
        $kagenstock = $request->input('kagenstock');
        

       
        $nonon = new Product();

        // メーカーの検索部分の値挿入
        $model = new Company();
        $companies = $model ->getCompanyNameById();


        // ソート機能と検索機能
        $products = $nonon->search($keyword,$search,$jougenprice,$kagenprice,$jougenstock,$kagenstock);

       
            
        return view('product', compact('products','keyword','companies','search','jougenprice','kagenprice','jougenstock','kagenstock'));
           
        
    }
0

3Answer

jQuery ajax のコードが動かないということですよね。であれば、Fiddler などのキャプチャツールを使って期待通り要求が出ていっているか、要求の内容はどうか、応答が返ってきているかを調べてください。

それができる環境を今現在すでに持っていて、今すぐ問題の切り分けができるのは質問者さんだけです。なので、まずは質問者さんの方で問題の切り分けを行ってから、それで分からないことがあればそこを質問するようにしましょう。

0Like

Comments

コードだけ見ての推測なので、動くようになるかは分かりませんが。

おそらくセレクトボックスを変更したら ajax を走らせたいのかなといました。

<select class="form-control" name="search" id="search">
  <option>{{"メーカーを選択してください"}}</option>
  <option>{{""}}</option>
  @foreach ($companies as $company)
    <option>{{ $company->company_name }}</option>
  @endforeach
</select>

それで ajax のコードが下記の通り
search クラスの要素をクリックしたら route('product') に対して get アクセスを行う、となっておりますが

$(".search").click(function(){
  $.ajax({
    type:"GET",
    url:"{{ route('product') }}",
    dataType: 'json',
  })   
  .done(function(json){
    //通信成功で実行される処理
    console.log(json);
  })
  .fail(function(){
    //通信が失敗した時に実行される処理
  })
  .always(function(){
      //通信の成功と失敗に関わらず実行される処理
  });
});

search クラスが付いている要素が多いです。div にもついています。

<div class="search">
<select class="form-control" name="search" id="search">

このままだと div 要素をクリックしても ajax が走ってしまいます。

修正内容としては id での指定にしてセレクトボックス要素でのみ動かすようにするのと、セレクトボックスで ajax を動かしたいのでしたら click() ではなく「値が変更されたら」の change() がふさわしいかと思います。

click() だとセレクトボックスに触れた瞬間に動いてしまうので。

// id で指定する。click() ではなく change()
$("#search").change(function(){
  $.ajax({
    type:"GET",
    url:"{{ route('product') }}",
    dataType: 'json',
  })   
  .done(function(json){
    alert('ajax成功');
  })
  .fail(function(){
    alert('ajax失敗');
  })
  .always(function(){
      //通信の成功と失敗に関わらず実行される処理
  });
});

成功可否については console 出力じゃなくてアラート出力にしました。

0Like

あと class の指定にドットを使うのは初めて見たのですが、記法としては正しくなかったような…?
アンダーバーとかにした方がいいかもしれません。

<!-- <div class="price.search"> -->
<div class="price_search">
0Like

Your answer might help someone💌