Laravel search functionality - laravel

I've got a searchbar on my homepage which looks like this:
<form action="{{ route('search', $query) }}" method="GET" role="search">
<div class="input-group mb-4 search_bar">
<input type="search" name="search" placeholder="Search..." aria-describedby="button-addon5" class="form-control search_input">
<div class="input-group-append">
<button id="button-addon5" type="submit" class="btn btn-primary"><i class="fa fa-search"></i></button>
</div>
</div>
</form>
My route looks like this:
Route::get('all-{query}-posts', 'SearchController#index')->where('query', '[A-Za-z0-9-]+')->name('search');
So basically I want the input of the searchbar in my url like this: /all-stuff-posts instead of the usual: ?search=stuff
It seems to automatically add the ?search=stuff to the end even though I didn't add that anywhere so that's the first problem.
The second problem is that I can only retrieve the query in the controller but that gives me an error in web.php because the query is still not set. Is there a different way of doing this that does work?

Change your form action method below like this
<form action="{{url('')}}/all-{{$query}}-posts" ...>

Used Post method.
<form action="{{ route('search', $query) }}" method="POST" role="search">

If you want to develop a search engine in your app, I will suggest the following. (One of the simplest ways).
Learn about POST, GET, PUT first.\
Then, My model like this
public function scopeSearchByKeyword($query, $keyword,$location)
{
if ($keyword!='' and $location!='') {
$query->where(function ($query) use ($keyword,$location) {
$query->where("title", "LIKE","%$keyword%")
->where("location_id", "$location")
->where("status", "1");
});
}
else
{
$query->where(function ($query) use ($keyword) {
$query->where("title", "LIKE","%$keyword%")
->where("status", "1");
});
}
return $query;
}
Here I am searching by title and location. It can output even if only a keyword is entered.
Then my controller like this:
public function search_kasblar(Request $request)
{
$inputs = $request->all();
$keyword = $inputs['search_keyword'];
$location = $inputs['location'];
$jobs= JobBoards::SearchByKeyword($keyword,$location)->get();
$total_res=count($jobs);
return view('jobs.search',compact('jobs','total_res','keyword'));
}
Here we can search for incoming data in the input.
So my view blade like this:
<div class="finderform">
{!! Form::open(array('url' => 'listings/search','class'=>'','id'=>'search','role'=>'form')) !!}
<div class="col-md-5 col-sm-5 no-padding"> <i class="fa fa-search local-search-ic"></i>
<input type="text" class="form-control" name="search_keyword" id="input-search-term" title="Search for..." placeholder="Search anything here" value="" autocomplete="off">
</div>
<div class="form-group col-md-5 col-sm-5 no-padding"> <i class="fa fa-map-marker local-search-ic ic-map-location"></i>
<div class="">
<select id="location" name="location" class="form-control">
<option value="">Select Location</option>
#foreach(\App\Location::orderBy('location_name')->get() as $location)
<option value="{{$location->id}}">{{$location->location_name}}</option>
#endforeach
</select>
</div>
</div>
<button type="submit" class="btn tp-btn-default tp-btn-lg">Search</button>
{!! Form::close() !!}
You can use like this.
And use POST in your router...

Related

pass user request in form action route in laravel 8

here is my simple form
<form id="test-form" class="white-popup-block mfp-hide">
<div class="popup_box ">
<div class="popup_inner">
<h3>Make an Appointment</h3>
<form action="{{route('doctorwithdatepopup',['date'=>$date,'id'=>$doctorsid])}}" method="POST">
#csrf
<div class="row">
<div class="col-xl-6">
<input id="datepicker" placeholder="Pick date" name="date">
</div>
#php
$Department = DB::table('departments')->orderBy('id','desc')->get();
#endphp
<div class="col-xl-6">
<select class="form-select wide" id="departmentid" name="departmentid">
<option data-display="Select Department">Department</option>
#foreach ($Department as $item)
<option value="{{$item->id}}">{{$item->name}}</option>
#endforeach
</select>
</div>
<div class="col-xl-12">
<select class="form-select wide" id="doctorsid" name="doctorsid" class="">
</select>
</div>
<br>
<br>
<div class="col-xl-12">
<button type="submit" class="boxed-btn3">Search</button>
</div>
</div>
</form>
</div>
</div>
</form>
inaction ['date'=>$date,'id'=>$doctorsid] these two data I want pass based on user selection how can I do that?
for example
$date = $request->date
this one can handle in the controller but in action URL how can I pass user enter values ?
Little tricky. Try to make 2 routes for that, first route to get user form requests. Second, your "doctorwithdatepopup" routes.
web.php
Route::post('url', [YourController::class, 'store'])->name('storeform');
Route::get('url2/{date}/{id}', [YourController::class, 'show'])->name('doctorwithdatepopup');
YourController.php
public function store(Request $request)
{
// Some Validation, Logic, etc
return redirect()->route('doctorwithdatepopup', ['date' => $request->date, 'id' => $doctorId]);
}
public function show($date, $id)
{
return view('your view', compact('date', 'id'));
}

Long link when I redirect to index

I have the following form:
<form action="/compras" method="POST">
#csrf
<div class="container">
<div class="row">
<div class="col-sm-6">
<select class="form-control" id="productor" name="productor">
<option value="0">Selecciona Productor</option>
#foreach ($productores as $productor)
<option value="{{$productor->id}}">{{$productor->nombre}}</option>
#endforeach
</select>
</div>
<div class="col-sm 6">
<select class="form-control" id="proveedor" name="proveedor">
<option value="0">Selecciona Proveedor</option>
#foreach ($proveedores as $proveedor)
<option value="{{$proveedor->id}}">{{$proveedor->nombre}}</option>
#endforeach
</select>
</div>
<button class="btn btn-secondary mr-2" name="action" value="search" type="submit">Buscar</button>
<button class="btn btn-secondary" name="action" value="create" type="submit">Crear</button>
</div>
</div>
</form>
I don't actually need to save data to the database in this controller, however I used the store function because of the post route that it includes. The idea is that if you press the Buscar button it will redirect to index filtering the table with the parameters, if you press Crear button it will redirect to a different controller and do something different
public function store(Request $request)
{
switch($request->input('action')){
case 'create':
return Redirect::action('ComprandoController#index', array('productor'=> $request->productor, 'proveedor'=>$request->proveedor));
break;
case 'search':
return Redirect::action('ComprasController#index', $request);
break;
}
}
The code is working as intended but when I redirect to index I have a problem in the link.
The link before filtering is: 127.0.0.1:4545/compras but after the filter it's something like
http://127.0.0.1:4545/compras?POST%20/compras%20HTTP/1.1%0D%0AAccept:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8%0D%0AAccept-Encoding:%20%20%20%20%20%20%20%20%20%20%20gzip,%20deflate%0D%0AAccept-Language:%20%20%20%20%20%20%20%20%20%20%20es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3%0D%0AConnection:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20keep-alive%0D%0AContent-Length:%20%20%20%20%20%20%20%20%20%20%20%2085%0D%0AContent-Type:%20%20%20%20%20%20%20%20%20%20%20%20%20%20application/x-www-form-urlencoded%0D%0ACookie:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20XSRF-TOKEN=eyJpdiI6IlhvQkVGa2libnlydUcyRDNQVElRdlE9PSIsInZhbHVlIjoiZWh0d091RUphUE9BV0t0dUtjY2w0akw4VEx2TjkxaVIySXFKWmpJbkVueVU5cHpHZXgvQ3l0TGc0U28zNFAwNSIsIm1hYyI6IjEzMDk3NTI5MWRjOTI2Nzg3YjA4ZWNiYTVlODZjN2ZjMGJjMWFjNWRkNjRjNjcwNDYwOWI5YjBjODE3NmRkMWUifQ%3D%3D;%20laravel_session=eyJpdiI6IkFCcGR2d01xZmwwbmh4dGprMGNYZHc9PSIsInZhbHVlIjoiVHI1aGUzWjVTdlgyVVE3WmFGV01PSjhTb01ZTWxnVllEL2Q2SmVxQ1BpVW5qY24yZjlLc01pdUVRNjNoRDEyTiIsIm1hYyI6ImFkNDI3NzBjZmUwZmRmZmE5ZDM2NjM1YTBkMWQyZjM2ZTUwOTQ4NjcwNzlhNGJkNzJhYjFlNTI1NjE5OTZjOWIifQ%3D%3D%0D%0AHost:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20127.0.0.1:4545%0D%0AOrigin:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20http://127.0.0.1:4545%0D%0AReferer:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20http://127.0.0.1:4545/compras?POST%20/compras%20HTTP/1.1%0D%0AAccept:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8%0D%0AAccept-Encoding:%20%20%20%20%20%20%20%20%20%20%20gzip,%20deflate%0D%0AAccept-Language:%20%20%20%20%20%20%20%20%20%20%20es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3%0D%0AConnection:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20keep-alive%0D%0AContent-Length:%20%20%20%20%20%20%20%20%20%20%20%2085%0D%0AContent-Type:%20%20%20%20%20%20%20%20%20%20%20%20%20%20application/x-www-form-urlencoded%0D%0ACookie:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20XSRF-TOKEN=eyJpdiI6IkpNVTA3dDk1cDZlSUhYNUorRndkamc9PSIsInZhbHVlIjoiK1JXTVFyN2dFcHJLaC9uK1QzMjhjQ1FTa2ZuQzFCM1FabnpiY3lXbzZPMzdVbGE2c0w2b3dWSlp5YnpMdVc0VyIsIm1hYyI6IjRhOTdjNTJiMTA1ODI2ODRmMDVhOTgyMDg1NTMxMzY1YzhiNTI2MGJhMzk1YzZjMzBhNTg5YmJhNDY0N2YzZDYifQ%3D%3D;%20laravel_session=eyJpdiI6ImU4bUUxenZUR0RCaTBJZis4WTg4TGc9PSIsInZhbHVlIjoiYkxucWdXNi81YmlvNzRUbjlqSEpxdUt3ZnBiazVxYURCaVBXSFYwbXZPU0hxTk1Sa2RFSDJVTkIyZUdHVTNGeSIsIm1hYyI6ImFmYWVjMjM1NmMwYTljMjkzNGQ4MmFlYjIwY2Q3MzJhMzI1OTY4MjUwM2ZkZmRhZmIyNTBjNmJiZjYxZDQ1NWQifQ%3D%3D%0D%0AHost:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20127.0.0.1:4545%0D%0AOrigin:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20http://127.0.0.1:4545%0D%0AReferer:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20http://127.0.0.1:4545/%0D%0AUpgrade-Insecure-Requests:%201%0D%0AUser-Agent:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Mozilla/5.0%20%28Windows%20NT%2010.0;%20Win64;%20x64;%20rv:80.0%29%20Gecko/20100101%20Firefox/80.0%0D%0ACookie:%20XSRF-TOKEN=fBi5Ch1lKRYNMLswqGIkUc94OOTjNTa8aNMmZ7h5;%20laravel_session=eV6iavmA0PGGAkisR1egs2mLHqbW6w9j58maOxDC%0D%0A%0D%0A_token=fBi5Ch1lKRYNMLswqGIkUc94OOTjNTa8aNMmZ7h5&productor=0&proveedor=0&action=search%0D%0AUpgrade-Insecure-Requests:%201%0D%0AUser-Agent:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Mozilla/5.0%20%28Windows%20NT%2010.0;%20Win64;%20x64;%20rv:80.0%29%20Gecko/20100101%20Firefox/80.0%0D%0ACookie:%20XSRF-TOKEN=fBi5Ch1lKRYNMLswqGIkUc94OOTjNTa8aNMmZ7h5;%20laravel_session=eV6iavmA0PGGAkisR1egs2mLHqbW6w9j58maOxDC%0D%0A%0D%0A_token=fBi5Ch1lKRYNMLswqGIkUc94OOTjNTa8aNMmZ7h5&productor=1&proveedor=3&action=search
How could I get rid of the grotesque big link without ruining the working code?
Can you add your route file ?
I prefer use return redirect()->route('route.name', ['id' => 1]); to do redirect from controller.
https://laravel.com/docs/7.x/redirects#redirecting-named-routes
Also, you can use $request->all() or $request->only(['productor', 'proveedor']).
PS : the link is long, because Laravel serialize all datas from $request.

PUT/POST in Laravel

I'm brand new to Laravel and am working my way through the [Laravel 6 from Scratch][1] course over at Laracasts. The course is free but I can't afford a Laracasts membership so I can't ask questions there.
I've finished Section 6 of the course, Controller Techniques, and am having unexpected problems trying to extend the work we've done so far to add a few new features. The course has students build pages that let a user show a list of articles, look at an individual article, create and save a new article, and update and save an existing article. The course work envisioned a very simple article containing just an ID (auto-incremented in the database and not visible to the web user), a title, an excerpt and a body and I got all of the features working for that, including updating an existing article and saving it.
The update form sets method to POST but then uses a #METHOD('PUT') directive to tell the browser that it is actually supposed to do a PUT. This worked perfectly in the original code. However, now that I've added two more fields to the form, when I click Submit after editing an existing record, the save fails with this message:
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
The PUT method is not supported for this route. Supported methods: GET, HEAD, POST.
http://localhost:8000/articles
I don't understand why adding two fields to the form would cause this to break. Can someone enlighten me? I added the two new fields/columns to the migration and ran migrate:rollback and migrate. I've also added the new fields/columns to the fillable attribute and added validations for them in the ArticlesController.
Here is my routing:
Route::get('/articles', 'ArticlesController#index');
Route::post('/articles', 'ArticlesController#store');
Route::get('/articles/create', 'ArticlesController#create');
Route::get('/articles/{article}', 'ArticlesController#show');
Route::get('/articles/{article}/edit', 'ArticlesController#edit');
Route::put('/articles/{article}', 'ArticlesController#update');
//Route::delete('/articles/{article}', ArticlesController#destroy');
This is my ArticlesController:
<?php
namespace App\Http\Controllers;
use App\Article;
use Illuminate\Http\Request;
class ArticlesController extends Controller
{
public function index()
{
$articles = Article::latest()->get();
return view ('articles.index', ['articles' => $articles]);
}
public function show(Article $article)
{
return view('articles.show', ['article' => $article]);
}
public function create()
{
return view('articles.create');
}
public function store()
{
//Stores a NEW article
Article::create($this->validateArticle());
return redirect('/articles');
}
public function edit(Article $article)
{
return view('articles.edit', ['article' => $article]);
}
public function update(Article $article)
{
//Updates an EXISTING article
$article->update($this->validateArticle());
return redirect('/articles/', $article->id);
}
public function validateArticle()
{
return request()->validate([
'title' => ['required', 'min:5', 'max:20'],
'author' => ['required', 'min:5', 'max:30'],
'photopath' => ['required', 'min:10', 'max:100'],
'excerpt' => ['required', 'min:10', 'max:50'],
'body' => ['required', 'min:50', 'max:500']
]);
}
public function destroy(Article $article)
{
//Display existing record with "Are you sure you want to delete this? Delete|Cancel" option
//If user chooses Delete, delete the record
//If user chooses Cancel, return to the list of articles
}
}
Here's my edit form, edit.blade.php:
#extends('layout')
#section('content')
<div id="wrapper">
<div id="page" class="container">
<h1>Update Article</h1>
<form method="POST" action="/articles">
#csrf
#method('PUT')
<div class="form-group">
<label class="label" for="title">Title</label>
<div class="control">
<input class="form-control #error('title') errorborder #enderror" type="text" name="title" id="title" value="{{ $article->title }}">
#error('title')
<p class="errortext">{{ $errors->first('title') }}</p>
#enderror
</div>
</div>
<div class="form-group">
<label class="label" for="author">Author</label>
<div class="control">
<input class="form-control #error('author') errorborder #enderror" type="text" name="author" id="author" value="{{ $article->author }}">
#error('title')
<p class="errortext">{{ $errors->first('author') }}</p>
#enderror
</div>
</div>
<div class="form-group">
<label class="label" for="photopath">Path to Photo</label>
<div class="control">
<input class="form-control #error('photopath') errorborder #enderror" type="text" name="photopath" id="photopath" value="{{ $article->photopath }}">
#error('title')
<p class="errortext">{{ $errors->first('photopath') }}</p>
#enderror
</div>
</div>
<div class="form-group">
<label class="label" for="excerpt">Excerpt</label>
<div class="control">
<textarea class="form-control #error('excerpt') errorborder #enderror" name="excerpt" id="excerpt">{{ $article->excerpt }}</textarea>
#error('excerpt')
<p class="errortext">{{ $errors->first('excerpt') }}</p>
#enderror
</div>
</div>
<div class="form-group">
<label class="label" for="body">Body</label>
<div class="control">
<textarea class="form-control #error('body') errorborder #enderror" name="body" id="body">{{ $article->body }}</textarea>
#error('body')
<p class="errortext">{{ $errors->first('body') }}</p>
#enderror
</div>
</div>
<div class="control">
<button class="btn btn-primary" type="submit">Submit</button>
</div>
</form>
</div>
</div>
#endsection
Is there anything else you need to see?
[1]: https://laracasts.com/series/laravel-6-from-scratch/episodes/33?autoplay=true
Your Laravel route is:
Route::put('/articles/{article}', 'ArticlesController#update');
So your form action url should match that uri:
<form action="{{ url('/articles/'.$article->id) }}">
where the {article} parameter is the record id (you can read more about in the docs here).
Then in your controller update() method, you have:
return redirect('/articles/', $article->id);
which means redirect to /articles with status code $article->id (you can read more about in the docs here). I think you are trying to redirect to the show route, which is:
Route::get('/articles/{article}', 'ArticlesController#show');
So change the , (comma) to a . (dot) to concatenate the article id with the uri:
return redirect('/articles/' . $article->id);
The route in the form for /articles, However your route for updating should be /articles/{article}
Try this:
<form method="POST" action="/articles/{{ $article->id }}">

Laravel Cannot retrieve a specific record from a form

I am outputting a list from a database table 'books' like this:
function edit()
{
$books = Book::all();
return view('layouts/editbooks', ['books' => $books]);
}
And displaying them like this:
#extends('layouts.master')
#section('title')
#section('content')
<h1>Edit Book</h1>
<form action="{{url('editbook')}}" method="GET">
{{ csrf_field() }}
#foreach ($books as $book)
<div>
<label>{{$book->title}}</label>
<input type='radio' value='{{$book->id}}' name='books[]'/>
</div>
#endforeach
<input type="submit" class="btn btn-warning form-control" value="Edit">
</form>
#endsection
I then want user to choose which record they want to edit by selecting a radio button, and upon clicking a submit button, redirect user to a new page with details of a book.
Therefore I am trying to get a book id from radio button and then if id matches, display everything from that record:
function editing(Request $request)
{
$edit = $request->books;
return view('layouts/editing', ['edit' => $edit]);
}
function updateEdit()
{
$books = DB::table('books')->where('id', $edit)->first();
}
And that is displayed in a view:
#extends('layouts.master')
#section('title')
#section('content')
<h1>Delete Book</h1>
<form action="{{url('removebook')}}" method="POST">
{{ csrf_field() }}
<div>
<input name="name" type="textbox" value="{{ old('name', $edit['name']) }}"/>
</div>
<input type="submit" name="submitBtn" value="Delete Book">
</form>
#endsection
However I get an error message saying:
Undefined index: name (View: C:\xampp\htdocs\laraveladvweb\resources\views\layouts\editing.blade.php)
What is causing the issue?
Isn't $edit just the id of the book?
try this
function editing(Request $request)
{
$edit = $request->books;
$book = DB::table('books')->where('id', $edit)->first();
return view('layouts/editing', ['edit' => $book]);
}
#extends('layouts.master')
#section('title')
#section('content')
<h1>Delete Book</h1>
<form action="{{url('removebook')}}" method="POST">
{{ csrf_field() }}
<div>
<input name="name" type="textbox" value="{{ old('name', $edit['name']) }}"/>
</div>
<input type="submit" name="submitBtn" value="Delete Book">
</form>
#endsection

Laravel 5 session()->keep method not working

I have a view with an input date field and a table beneath that. The table is populated based on the date entered. When the date is entered I use a POST method on the form which handles the DB request and returns the same view with the data. I'd like to also return the original date that was entered. I tried session()->keep and flashOnly methods. None return the input date to the view.
My controller:
public function groupTestAthletes(Request $request)
{
$inputDate = null;
$tests = null;
if ($request['tgroupdate']){
$inputDate = Carbon::createFromFormat('d/m/Y', $request['tgroupdate']);
$tests = Test::where('test_date', '=', $inputDate->format('Y-m-d'))
->orderBy('athlete_id', 'desc')
->get();
}
$request->session()->keep(['tgroupdate']);
//$request->flashOnly(['tgroupdate']);
return view('npr.test_athletes', ['tests' => $tests]);
My view:
<form class="form-inline" role="form" method="POST" action="{{ route('admin.search_tgroup') }}">
{{ csrf_field() }}
<div class="form-group">
<label for="tgroupdate" class="control-label">Test Date</label>
<div class="input-group date" id="testgroupdatepicker">
<input name="tgroupdate" type="text" style="background-color:#ffffff" readonly=""
value="{{ Session::get('tgroupdate') }}" class="form-control">
<div class="input-group-addon">
<span class="glyphicon glyphicon-th"></span>
</div>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Search Athletes
</button>
<input type="hidden" name="_token" value="{{ Session::token()}}">
</div>
</form>
You dont need to save the date in session. You can save the date in a variable,send it to the view and in the view you can check if variable exist using isset php function.
In Controller
public function groupTestAthletes(Request $request)
{
$inputDate = null;
$tests = null;
if ($request['tgroupdate']){
$inputDate = Carbon::createFromFormat('d/m/Y', $request['tgroupdate']);
$tests = Test::where('test_date', '=', $inputDate->format('Y- m-d'))
->orderBy('athlete_id', 'desc')
->get();
}
return view('npr.test_athletes', ['tests' => $tests,'selected_date' => $request['tgroupdate']]);
And in the view,
<form class="form-inline" role="form" method="POST" action="{{ route('admin.search_tgroup') }}">
{{ csrf_field() }}
<div class="form-group">
<label for="tgroupdate" class="control-label">Test Date</label>
<div class="input-group date" id="testgroupdatepicker">
<input name="tgroupdate" type="text" style="background-color:#ffffff" readonly=""
value="#if(isset($selected_date)) $selected_date #endif" class="form-control">
<div class="input-group-addon">
<span class="glyphicon glyphicon-th"></span>
</div>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Search Athletes
</button>
<input type="hidden" name="_token" value="{{ Session::token()}}">
</div>
</form>
Edit: This minor change in the view gave the optimal solution.
value="#if(isset($selected_date)){{$selected_date}}#endif"

Resources