Laravel search not returning any result - laravel

I am trying to create a search where user can search for book title. There is a field in 'books' table called 'title'.
however if I do dd($books); I get:
Collection {#667 ▼
#items: []
}
If I do dd($searchTerms); output seems to be correct
Here's my controller:
function search()
{
$books = Book::all();
return view('layouts/search',['books' => $books]);
}
function details() {
$searchTerms = explode(' ', \Request::input('book'));
$books = Book::where(function($q) use($searchTerms) {
foreach ($searchTerms as $book) {
$q->orWhere('title', '%'.$book.'%');
}
})->get();
dd($books);
return view('layouts/details', compact('books'));
}
Search blade:
#extends('layouts.master')
#section('title')
#section('content')
<h1>Search for books</h1>
<form action="{{url('details')}}" method="POST">
{{ csrf_field() }}
<div>
<input type='text' name='book' placeholder='Enter any character' />
</div>
<input type="submit" name="submitBtn" value="Search">
</form>
#endsection
Details blade:
#extends('layouts.master')
#section('title')
#section('content')
<h1>User Details</h1>
<form>
<p>
<ul>
#foreach ($books as $book)
<a href= "{{url('reader/'.$book->title)}}">
{{$book->title}}</a>
</p>
</form>
#endforeach
</ul>
#endsection

You forgot to tell the eloquent builder that your OR's should have LIKE as the operator:
$q->orWhere('title', 'like', '%'.$book.'%');

Please change the function of details to this
function details(Request $request) {
$searchTerms = $request->book;
$books = Book::where(function($q) use($searchTerms) {
foreach ($searchTerms as $book) {
$q->orWhere('title', '%'.$book.'%');
}
})->get();
dd($books);
return view('layouts/details', compact('books'));
}

Related

Livewire: problem whit display data and form

I have problem with display data and form on one page.
Display data from database disappear after write in textarea any word. The same problem ist when i click on submit. In debugger is only data from first query, from second is cleared.
I try with one query (second), but it's the same.
My example code
route web:
Route::middleware(['auth:sanctum', 'verified'])->get('/tickets/show/{slug}', Tickets\Show::class)->name('tickets.show');
Livewire:
public $ticket;
public $slug;
public $posts;
public $content_post;
public $ticket_id;
public function mount($slug){
$this->ticket = Tickets::where('tickets.id','=', $slug)->join('users', 'users.id', '=', 'tickets.user_id')
->select('users.email','users.phone','users.username','users.first_name','users.last_name','tickets.user_id','tickets.created_at',
'tickets.id', 'tickets.subject','tickets.status_id','tickets.admin_id')->first();
$this->posts = TicketsPost::where('tickets_posts.ticket_id','=', $slug)->join('users', 'users.id', '=', 'tickets_posts.user_id')
->select('users.email','users.username','users.first_name','users.last_name','tickets_posts.user_id','tickets_posts.created_at',
'tickets_posts.ticket_id','tickets_posts.post')->get();
}
public function addPost()
{
$this->validate([
'content_post' => 'required'
]);
$user_id = Auth::user()->getAuthIdentifier();
TicketsPost::create([
'ticket_id' => $this->ticket_id,
'user_id' => $user_id,
'post' => $this->content_post,
]);
}
public function render()
{
return view('livewire.tickets.show');
}
View:
<p >#{{$ticket->id}}</p>
<p >{{$ticket->subject}}</p>
#foreach($posts as $post)
<p >{{$post->first_name}} {{$post->last_name}}</p>
<p >{{ date('d.m.Y H:i',strtotime($post->created_at)) }}</p>
<p > {{$post->post}}</p>
#endforeach
<form >
<input type="hidden" name="ticket_id" value="2" wire:model="ticket_id">
<textarea name="content_post"
class=""
rows="5" required="" placeholder="Treść wiadomości" wire:model="content_post"></textarea>
#error('content_post') <span class="text-red-500">{{ $message }}</span>#enderror
<button wire:click.prevent="addPost()" type="submit" class="">
<span id="btn_text" class="ml-2">Dodaj</span>
</button>
</form>
In Livewire, make sure your component has a single-level root element only.
And, don't forget to add wire:key in your element inside every loop in a blade.
Your loop should be as;
#foreach($posts as $key => $post)
<div wire:key="{{'post'.$key}}">
<p>{{$post->first_name}} {{$post->last_name}}</p>
<p >{{ date('d.m.Y H:i',strtotime($post->created_at)) }}</p>
<p > {{$post->post}}</p>
</div>
#endforeach

How to send parameter by view

I send the parameter by url in view but I get an error of the undefined variable but I don't understand why if I am not sent that variable.
enter image description here
web.php
Route::get('acceso/{url}', 'AccesoController#index')->name('acceso');
Route::put('acceso/user-id/{url}', 'AccesoController#update');
acceso.blade.php
<form method="POST" action="{{ url('acceso/user-id', ['url' => $url]) }}">
#csrf
#method('PUT')
<h1 class="h3 mb-3 fw-normal">Bienvenido a Suprapp, {{ old('title', $acceso->name) }}</h1>
<button type="submit" class="w-100 btn btn-lg btn-primary">Acceso a la APP</button>
<p class="mt-5 mb-3 text-muted">© 2017-2020</p>
</form>
AccesoController.php
public function index($url)
{
$users = User::where('url', $url)->get();
foreach ($users as $user) {
return view('acceso', ['url' => $user->id]);
}
}
public function update(Request $request, $url)
{
//$data = $request->all();
$user = User::find($url);
$user->ip_acceso = $request->ip();
$user->url = $request->url();
$user->save();
return redirect()->route('login', ['url' => $user->id]);
}
thanks for your help
The following line is causing your problem:
<h1 class="h3 mb-3 fw-normal">Bienvenido a Suprapp, {{ old('title', $acceso->name) }}</h1>
You're using a variable $accesso but do not pass it through when you return your view.
public function index($url)
{
$users = User::where('url', $url)->get();
foreach ($users as $user) {
return view('acceso', ['url' => $user->id]); // no accesso passed
}
}

search by multiple values using checkbox in laravel

I have job_sector table in which sector_id and job_id fields are there. I just want to search job_id by the sectors which I have selected through checkbox. One may select multiple sectors.
My model :
public function scopeSelectedOptions($query, $input = [])
{
if(!empty($input)) {
if(array_key_exists('sector_id', $input)) {
$query->whereHas('sector_id', function($q) use ($input) {
return $q->whereIn('sector_id', $input['sector_id']);
});
}
}
return $query;
}
Controller :
public function jobsFilter(Request $request)
{
$jobs = JobSector::SelectedOptions(request()->all())->get();
return view('front.pages.job.jobfilter')->with(['title'=>'Job Filter', 'jobs' => $jobs]);
}
Form from where I am selecting multiple sectors :
<form action="{{ route('job.jobfilter') }}" method="GET" class="mb-4">
{{csrf_field()}}
#foreach(get_sectors() as $k=>$s)
<input type="checkbox" name="input[]" value="{{ $k }}">{{ $k }}<br>
#endforeach
<input type="submit" value="Search" />
</form>
Query showing the output :
#foreach($jobs as $c)
{{ $c->job_id }} <br>
#endforeach
It shows me all the job_id in the table.
Please help me out,
You are giving the wrong array to your scope
it would look like this :
['input' => ['12' => true]]
try this
<form action="{{ route('job.jobfilter') }}" method="GET" class="mb-4">
{{csrf_field()}}
#foreach(get_sectors() as $k=>$s)
<input type="checkbox" name="sector_id[{{ $k }}]">{{ $k }}<br>
#endforeach
<input type="submit" value="Search" />
</form>
public function jobsFilter(Request $request)
{
$jobs = JobSector::whereIn('sector_id', array_keys(request()->sector_id))->get();
return view('front.pages.job.jobfilter')->with(['title'=>'Job Filter', 'jobs' => $jobs]);
}
(I just ignore your scope to be more readable)

Get related products for a product by category

I'm trying to show products related to a category. But it is showing all products which are also related to other categories.
Blade:
<div class="row">
#foreach($categories as $category)
#foreach ($category->products as $product)
<div class="col-sm-12 col-md-6 col-lg-4 p-b-50">
<!-- Block2 -->
<div class="block2">
<div class="block2-img wrap-pic-w of-hidden pos-relative block2-labelnew">
<img src="{{ URL::to('/') }}/images/backend_images/product_images/{{ $product->product_image }}"
class="img-thumbnail" style="width: 270px; height: 360px;" />
<div class="block2-overlay trans-0-4">
</div>
</div>
<div class="block2-txt p-t-20">
<a href="product-detail.html" class="block2-name dis-block s-text3 p-b-5">
{{ $product->product_name }}
</a>
<span class="block2-price m-text6 p-r-5">
$75.00
</span>
</div>
</div>
</div>
#endforeach
#endforeach
</div>
Controller:
public function products(Request $request, Product $product)
{
$categories = Category::with('products')->distinct()->get();
return view('product.listing', compact('product', 'categories'));
}
Route:
Route::get('/product/{id}','Admin\ProductController#products')->name('product.products');
Edit your controller:
public function products(Request $request, Product $product)
{
$categories = $product->categories;
return view('product.listing', compact('product', 'categories'));
}
Also you should have the categories relationship method on Product Model.
public function products(Request $request, Category $category)
{
$products = Product::where('category_id',$category->id)->get();
$categories = Category:all();
return view('product.listing', compact('products','categories'));
}
Your route is
Route::get('/product/{id}','Admin\ProductController#products')->name('product.products');
//{id} it means you're getting category id from route right? so you can directly access it in controller.
Controller
//$id is from route.
public function products($id)
{
$products = Product::with('category')->where('category_id',$id)->get();
return view('product.listing', compact('products'));
}
In your blade file
#foreach($products as $product)
//here your all product which belongs to that categories.
and now if you want to access categories then may do as.
categories :- {{ $product->category->name }} //make sure it belongsTo in product
#endforech
public function products(Request $request)
{
$categories = Category::where('id',$request->id)->with('products')->get();
return view('product.listing', compact('categories'));
}
#foreach($categories as $category)
#foreach ($category as $product)
Assuming a product has one category and you have a category_id column in your products table change products method in your ProductController like below.
public function products(Request $request, Product $product)
{
$relatedProducts = Product::where('category_id', $product->category_id)
->where('id', '!=', $product->id) // ignore current product
->get();
return view('product.listing', compact('product', 'relatedProducts'));
}
Replace id in your route withproduct`. Read More about route model binding.
Route::get('/product/{product}','Admin\ProductController#products')->name('product.products');
Then in your view your you can iterate through relatedProducts
controller:
public function products(Request $request, Category $category)
{
$category->load('products');
return view('product.listing', compact('category'));
}
route:
Route::get('/product/{category}','Admin\ProductController#products')->name('product.products');
blade file:
#foreach ($category->products as $product)
<div class="col-sm-12 col-md-6 col-lg-4 p-b-50">
<!-- Block2 -->
<div class="block2">
<div class="block2-img wrap-pic-w of-hidden pos-relative block2-labelnew">
<img src="{{ URL::to('/') }}/images/backend_images/product_images/{{ $product->product_image }}" class="img-thumbnail" style="width: 270px; height: 360px;" />
</div>
</div>
</div>
#endforeach

Undefined variable: posts when passing parameter from controller to view

I'm trying to create a search function in Laravel and its returning me with "undefined variable: posts" when I do foreach on my view.
My code:
Post Model
class Post extends Model {
protected $fillable = [
'creator',
'post_url',
'books',
'likes',
'created_at'
];
public function user() { return $this->belongsTo(User::class); }
}
Homeview:
<form action="{{ url('/search') }}" method="get">
<input type="text" class="search-text form-control form-control-lg" name="q" placeholder="Search" required>
</form>
Controller:
public function search($keyword)
{
$result = Post::where('books', 'LIKE', "'%' . $keyword . '%'")->get();
return view('/search', ['posts' => $result]);
}
Route:
Route::get('/search/{keyword}', 'SearchController#search');
Searchview:
#foreach($posts as $post)
<div class="post">{{ $post->id }}</div>
#endforeach
What am I doing wrong here?
This might help you out.
Homeview.blade.php
<form action="/search" method="POST">
#csrf // include your csrf token
<input type="text" class="search-text form-control form-control-lg" id="q" name="q" placeholder="Search" required>
</form>
Searchview.blade.php
<!-- or did you return a collection? -->
#if( $posts->count() > 1 )
<!-- then loop through the posts -->
#foreach( $posts as $post )
<div class="post"> {{ $post->id }} </div>
#endforeach
#else
#if( !empty($posts) )
<div class="post"> {{ $post->id }} </div>
#endif
#endif
Routes/web.php
Route::post('/search', 'PostsController#show')->name('posts.show');
PostsController
use App\Post;
public function show( Request $request )
{
$result = Post::where("books", "LIKE", "%{$request->input('q')}%")->get();
// Uncomment the following line to see if you are returning any data
// dd($result);
// Did you return any results?
return view('searchview', ['posts' => $result]);
}
The reason it wasn't working,
Route::get('/search/{keyword}', 'SearchController#search');
In your route file you were looking for a {keyword} that was never passed by the form. Your form action is action="{{ url('/search') }}". A get variable will not be picked up by a route and if it was you called the input 'q' anyway.
So then in your controller you were looking for the keyword being passed that is never passed in.
public function search($keyword)
Instead the correct thing to do is pass in the Request object like so
public function search(Request $request)
Then use $request->input('q') to retrieve the passed value through your form.
In your example $keyword would always have been blank.
Corrected code
Homeview:
<form action="{{ url('/search') }}" method="get">
<input type="text" class="search-text form-control form-control-lg" name="q" placeholder="Search" required>
</form>
Controller:
public function search(Request $request)
{
$result = Post::where('books', 'LIKE', "%{$request->input('q')}%")->get();
return view('/search', ['posts' => $result]);
}
Route:
Route::get('/search', 'SearchController#search');
Searchview:
#foreach($posts as $post)
<div class="post">{{ $post->id }}</div>
#endforeach
try:
return view('/search')->with('posts', $result);
Or even better with dinamic vars.
return view('/search')->withPosts($result);

Resources