1

I have a site that displays every post that is stored in a database with a search bar at the top. Obviously when the user first visits the page no search term is applied and all posts are visible.

When the user then searches for a word and presses the search button everything works fine. However, when you delete the string from the search bar and press search again all posts are gone, of course going back with mouse buttons works and reloading aswell. But I would like to achieve that when the empty search bar is submitted all posts appear.

This is the form:

<form action=" {{ route('overview') }}" method="get">
    <div>
        <input placeholder="Schlagwort" type="text" id="s" name="s" value="{{ request()->get('s') }}">
    </div>
    <button type="submit">Suchen</button>
</form>

This is the controller with the search function:


public function index(Request $request) {

    $posts = Post::get();

    if($request->has('s')) {
        $query = strtolower($request->get('s'));
        $posts = $posts->filter(function ($post) use ($query) {
            if (Str::contains(strtolower($post->Titel), $query)) {
                return true;
            }
            return false;
        });

    } 
    return view('posts.overview', ['posts' => $posts]);
}

I tried this when trying to achieve the 'empty search bar display everything "feature" '

public function index(Request $request) {
    $posts = Post::get();

    if($request->has('s')) {
        $query = strtolower($request->get('s'));
        $posts = $posts->filter(function ($post) use ($query) {
            if (Str::contains(strtolower($post->Titel), $query)) {
                return true;
            }
            return false;
        });

    } else if ($request == ' ') {
        return view('posts.overview', ['posts' => $posts]);
    }
    return view('posts.overview', ['posts' => $posts]);
}

As well swapped out with else if ($request == null) ...

Edit: I got a question ban because my questions are not upvoted, but answered and some good discussion happens in the comments. But the stack exchange team told me to edit my questions to making them more clear, but they received answers so I think they were clear. I am not a native speaker so my English is not the best and I cant express myself that good. But they told me to edit them so they appear as new and can be upvoted. I don't see why that makes sense, but maybe it lifts my question ban if I get some upvotes, so maybe upvote if you don't mind.

Frevelman
  • 338
  • 3
  • 11
  • Hey @miken32 :) I want to display all posts (just like when a user first visits the page) when a user presses the search button with an empty search bar – Frevelman Nov 26 '21 at 20:28
  • 2
    Try `if($request->filled('s'))` – miken32 Nov 26 '21 at 20:32
  • @miken32 works like a charm! Thank you very much! Can you post it as an answer so I can flag it as correct? So others can see it aswell – Frevelman Nov 26 '21 at 20:37

1 Answers1

2

You are checking if the s input is present, when instead you want to check if it has a value. Use the filled() method for that.

In addition, you are needlessly fetching everything from the database and then filtering in PHP. Instead, build a query that checks for the input value using the when() method.

public function index(Request $request)
{    
    $posts = Post::query()
        ->when(
            $request->filled('s'),
            fn ($q) => $q->where('title', 'like', $request->s)
        )
        ->get();

    return view('posts.overview', ['posts' => $posts]);
}
miken32
  • 42,008
  • 16
  • 111
  • 154
  • Now that is a great answer! Thank you, shows me a whole different way on implementing it. I am fairly new to laravel so my code must look like a massacre to experienced people :D – Frevelman Nov 26 '21 at 20:44
  • 1
    Gotta start somewhere. I've updated the answer: string comparison is case-insensitive, at least in mysql – miken32 Nov 26 '21 at 20:48
  • Yeah i transformed everything to lower case, at least I thought that's the right way to do it. – Frevelman Nov 26 '21 at 20:52
  • 1
    In your original code filtering on the collection of all posts, it was needed. But when filtering in the database query, it is not. – miken32 Nov 26 '21 at 20:54