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
.