Home > Mobile >  Laravel cant seem to implement search properley
Laravel cant seem to implement search properley

Time:12-15

blade.php file that shows all Posts from my database Im trying to add a search bar that will filter all these posts to prioritise according to title but i cant seem to get it working at all

@extends('layouts.app')
@section('content')
<div >
  <div >
    <div >
      <div >
        <div >
          @if (Auth::user() && Auth::user()->is_admin)
            <h1 >Bloggy</h1><h2>Admin</h2>
          @endif  
        </div>
        <!-- Check to see if the user is a guest, if they are the Add post button is hidden -->
        @if(!Auth::guest())
          <div >
            <a href="posts/create/" >Add Post</a>
          </div>
        @endif
      </div>
      @if (Auth::user() && Auth::user()->is_admin)
        <div >
          <a href="/admin" >Manage Users</a>
        </div>
      @endif 
      <!-- HERE -->
      <form>
        <input type="search"  placeholder="Find user here" name="search">
      </form>
      @forelse($posts as $post)
        <ul>
          <li><a href="./posts/{{ $post->id }}">{{ ucfirst($post->title) }}</a></li>
          <li><a href="./posts/{{ $post->id }}">{{ ucfirst($post->created_at) }}</a></li>
        </ul>
        <p>
          <a href="{{ route('posts.showPostsByUser', $post->user) }}">{{ $post->user->name }}</a>
        </p>
        <p>
          <a href="/tags/{{ $post->tag->id }}">{{ $post->tag->name }}</a>
        </p>
      @empty
        <p >No blog Posts available</p>
      @endforelse
    </div>
  </div>
</div>
@endsection

Here is my posts controller

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use App\Models\User;
use Illuminate\Http\Request;

use Illuminate\Support\Facades\Auth;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $posts = Post::orderBy('created_at', 'desc')
        ->paginate(20);

        return view('posts/index', [
            'posts'=> $posts
        ]);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('posts/create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    // References
    // Jefferey Way. laracasts. Laravel 8 from scratch. laracasts.com. https://laracasts.com/series/laravel-8-from-scratch
    public function store(Request $request)
    {
        $request->validate([
            'tag_id' => 'required',
            'title'=> 'required',
            'body'=> 'required',
        ]);

        $post = new Post;
        //dd(Auth::user());
        $post->user()->associate(Auth::user());
        $post->title = $request->title;
        $post->body = $request->body;
        $post->tag_id = $request->tag_id;

        $post->save();

        return redirect()->route('posts.index')
            ->with('success', 'Post created succesfully');
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function show(Post $post)
    {
        return view('posts.show', [
            'post'=> $post,
        ]);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function edit(Post $post)
    {
        return view('posts.edit', [
            'post' => $post
        ]);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Post $post)
    {
        $request->validate([
            'title' => 'required',
            'body' => 'required'
        ]);

        $post->update($request->all());

        return redirect()->route('posts.index')
            ->with('success', 'Post updated succesfully');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function destroy(Post $post)
    {
        $post->delete();
        return redirect()->route('posts.index')
            ->with('success', 'Deleted Succesfully');
    }

    public function showPostsByUser(User $user)
    {
        $posts = Post::where('user_id', $user->id)->get();
        
        return view('posts.userposts', compact('posts', 'user'));
    }

    // Search function here
    public function search()
    {
        // Check for search input
        if (request('search')) {
            $posts = Post::where('title', 'like', '%' . request('search') . '%')->get();
        } else {
            $posts = Post::all();
        }

        return view('posts.show')->with('posts', $posts);
    }
}

Here is my routes file

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\WelcomeController;

use App\Http\Controllers\PostController;
use App\Http\Controllers\LoginController;

use App\Http\Controllers\CommentController;
use App\Http\Controllers\RegisterController;
use App\Http\Controllers\AdminController;
use App\Models\Tag;
use App\Model\Post;
use App\Model\Users;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', [WelcomeController::class, 'index']);

Route::resource('/posts', PostController::class);

Route::get('/posts/search', [PostController::class, 'search'])->name('search');

Route::post('posts/{post}/comments', [CommentController::class, 'store']);

Route::get('/register', [RegisterController::class, 'create'])->name('register.create')->middleware('guest');
Route::post('/register', [RegisterController::class, 'store'])->name('register.store')->middleware('guest');

Route::get('/login', [LoginController::class, 'login'])->name('login');
Route::get('/logout', [LoginController::class, 'logout'])->name('logout');

Route::post('/login', [LoginController::class, 'authenticate'])->name('authenticate');

Route::resource('/admin', AdminController::class)->middleware('admin');

// Route::get('/tags/{tag}', function(Tag $tag) {
//     return view('posts/index', [
//         'posts'=>$tag->posts
//     ]);
// });

Route::get('/posts/user/{user}', [PostController::class, 'showPostsByUser'])->name('posts.showPostsByUser');

I cant seem to get anything working when i search in the bar on the main page my url changes to http://localhost/posts?search=postname

And then nothing happens

Any help would be appreciated thanks, still trying to learn Laravel

EDIT: It just seems to stay on the same page just the url changes

CodePudding user response:

So you have a couple options here. You can define a separate route for /posts/search, or you can hook into the existing /posts (index) Route:

Define a GET Route for this new Search URL:

routes/web.php:

Route::get('/posts/search', [PostController::class, 'search'])->name('search');

PostsController.php:

public function search(Request $request) {
  $postsQuery = Post::latest(); // `latest()` is shorthand for `orderBy('created_at', 'DESC');`
  if ($request->has('search')) {
    $postsQuery = $postQuery->where('title', 'like', '%' . $request->input('search') . '%');
  }

  $posts = $postQuery->paginate(20);
  return view('posts.index', ['posts' => $posts]);
}

Lastly, update the <form> element for this Search function:

<form action="{{ route('search') }}">
  <input type="search"  placeholder="Find user here" name="search">
</form>

Now, when you navigate to http://localhost/posts/search, you'll get 20 Post records, ordered by created_at.

If you navigate to http://localhost/posts/search?search=example, you'll get up to 20 Post records, but only those that include example in their title.

You'll notice how similar that is to the index() method; so you can merge them to make your code a bit more "DRY" (Don't Repeat Yourself):

PostsController.php

public function index(Request $request) {
  $postsQuery = Post::latest();
  if ($request->has('search')) {
    $postsQuery = $postQuery->where('title', 'like', '%' . $request->input('search') . '%');
  }

  $posts = $postQuery->paginate(20);
  return view('posts.index', ['posts' => $posts]);
}

You don't need Route::get('/posts/search', ...); anymore. Instead, if you navigate to http://localhost/posts, you'll get the latest 20 Post records. If you navigate to http://localhost/posts?search=example, you'll get up to 20 Post records, ordered by created_at, but only those that include example in the title.

  • Related