jqueryajaxlaravelhreflivesearch

How to pass route links and image storage links via ajax in controller laravel 8


I'm new to ajax and I'm trying to build a live search box for users list in a chatbox, in order for the design to fit my chatbox I had to make the HTML the same as my template, the results are getting back fine it's just the link href isn't working also the users profile picture isn't found, I tried the traditional URL syntax but it seems not write with ajax , here is my controller search function :

    if($request->ajax())
    {
      $output = '';
      $query = $request->get('query');
      if($query != '')
      {
       $data = DB::table('users')
         ->where('id', 'like', '%'.$query.'%')
         ->orWhere('name', 'like', '%'.$query.'%')
         ->orWhere('email', 'like', '%'.$query.'%')
         ->orWhere('prenom', 'like', '%'.$query.'%')
         ->orWhere('ville', 'like', '%'.$query.'%')
         ->orWhere('tel', 'like', '%'.$query.'%')
         ->orderBy('id', 'desc')
         ->get();
         
      }
      else
      {
       $data = DB::table('users')
         ->orderBy('id', 'desc')
         ->get();
      }
      $total_row = $data->count();
      if($total_row > 0)
      {
       foreach($data as $row)
       {
        $output .= '<a  href="{{url("messages/' .$row->id. '")}}" title="Voir discussion">
                        <div class="media chat-list">
                            <div class="media-left thumb thumb-sm">
                                <img alt="" class="media-object chat-img" src="{{asset("storage/'.$row->picture.'")}}"
                            </div>
                            <div class="media-body">
                                <p class="media-heading m-b-10">
                                    <span class="text-strong">'.$row->name.' '.$row->prenom.'</span>
                                </p>
                            </div>
                        </div>
                    </a>';

       }
      }
      else
      {
        
       $output = '
        <li align="center" colspan="5">No Data Found</li>
     
       ';
      }
      $data = array(
       'table_data'  => $output,
       'total_data'  => $total_row
      );

      echo json_encode($data);
     }
  

and here is my Script:

     <script>
$(document).ready(function(){

    fetch_customer_data();

     function fetch_customer_data(query = '')
     {
      $.ajax({
       url:"{{ route('live_search.action') }}",
       method:'GET',
       data:{query:query},
       dataType:'json',
       success:function(data)
       {
        $('#result').html(data.table_data);
        $('#total_records').text(data.total_data);
        $('#inbox').hide();
       }
      })
     }

     $(document).on('keyup', '#search', function(){
      var query = $(this).val();
      fetch_customer_data(query);
     });
});
    </script>

And finally the code responsible for showing the result :

    <div class="form-group mt-20 is-empty">
    <input type="text" class="form-control" id="search" name="search" placeholder="Rechercher..."></input>
       <div id="result" class="chat-inactive">
                                           
       </div>
    </div>

Can someone please tell me what is the right syntax for the href link and the picture link! because I need the link so when the result is shown I can click and get the messages of the resulted user

Result of the search


Solution

  • The logic in your code seems ok, but you've written blade-specific syntax in controller, which will not convert the snippets as you want, that's why it not worked. But instead discussing that code, I recommend to use Laravel's best practices:

    There's a cool feature that Laravel provides. There is a "render()" method, which convert the blade content as HTML. So, instead of writing the HTML in controller's method, you can just write that HTML in some separated blade file (with $users argument in this case), render the response HTML, and send that back to the client as AJAX response (with JSON format). Like so:

    if($request->ajax()) {
        $query = $request->get('query');
        if(empty($query)) {
            $users = DB::table('users')
                ->orderBy('id', 'desc')
                ->get();
        } else {
            $users = DB::table('users')
                ->where('id', 'like', '%'.$query.'%')
                ->orWhere('name', 'like', '%'.$query.'%')
                ->orWhere('email', 'like', '%'.$query.'%')
                ->orWhere('prenom', 'like', '%'.$query.'%')
                ->orWhere('ville', 'like', '%'.$query.'%')
                ->orWhere('tel', 'like', '%'.$query.'%')
                ->orderBy('id', 'desc')
                ->get();
        }
        $total = $users->count();
    
        $html = view('path.to.some.blade.file', [
            'users' => $users,
        ])->render();
    
        return response()->json([
            'success' => true,
            'html' => $html,
            'total' => $total,
        ], 200);
    } else {
        return response()->json([
            'success' => false,
            'message' => "Something went wrong!",
        ], 403);
    }
    

    Here you can have your blade file like so:

    @if($users->count() > 0)
        @foreach($users as $user)
            <a href="{{ url('messages/' . $user->id) }}" title="Voir discussion">
                <div class="media chat-list">
                    <div class="media-left thumb thumb-sm">
                        <img alt="" class="media-object chat-img" src="{{ asset('storage/' . $user->picture) }}">
                    </div>
                    <div class="media-body">
                        <p class="media-heading m-b-10">
                            <span class="text-strong">{{ $user->name . ' ' . $user->prenom }}</span>
                        </p>
                    </div>
                </div>
            </a>
        @endforeach
    @else
        <div>No Data Found</div>
    @endif
    

    In your AJAX success function you just need to put the retrieved response HTML in some "#result" element:

    success: function(data) {
       if (data.success) {
          // needed part
          $('#result').html(data.html);
          $('#total_records').text(data.total);
    
          $('#inbox').hide();
       } else {
          console.log(data.message);
       }
    }
    

    p.s. I assume that you've succesfully getting the data from DB, also you can edit the blade HTML as well as the their style, etc.