Search Bar in Laravel with POST - php

I added a search bar in my Laravel application. Everything is working fine except for the fact that I am using $_GET instead of $_POST.
I am stuck on this part and don't know how to change the way it works.
That's my view:
<body>
<div class="container d-flex justify-content-end">
<div class="row">
<div class="col-md-12">
<form action="{{ route('search_bar_route') }}" method="GET">
<div class="form-group">
<input
type="text"
class="form-controll"
name="query"
placeholder="Serach Competitions"
/>
<button type="submit" class="btn btn-primary btn-sm ms-1 mb-1">
Search
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-search"
viewBox="0 0 16 16"
>
<path
d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z"
/>
</svg>
</button>
</div>
</form>
</div>
</div>
</div>
</body>
Function in the Controller:
public function index()
{
$competitions = Competition::orderby('id', 'DESC')->paginate(40);
if (isset($_GET['query'])) {
$search_bar_input = $_GET['query'];
$competitions = Competition::orderBy('id', 'DESC')
->where('name', 'LIKE', '%' . $search_bar_input . '%')
->paginate(1)
->withQueryString()
;
} else {
return view('competition.index', compact('competitions'));
}
return view('competition.index', compact('competitions'));
}
My route:
Route::get("/search", [CompetitionController::class, 'index'])->name('search_bar_route');

you need to figure how to use request in laravel we don't use $_GET or global var from PHP
if you send data by GET method you may need to use $request()->get(your name data ) as #ericmp mention comment in your problem
you can check laravel doc for farther info about http requests you may need in the following link : enter link description here
if you got an issue in a filter result you can edit the competitions to be like that
$competitions = Competition::orderBy('id', 'DESC')
->where('name', '%' . $search_bar_input . '%')
->paginate(1)
->withQueryString();
the best practice is
$competitions = Competition::orderBy('id', 'DESC')
->where('name', '%' . reuqest()->get('query'). '%')
->paginate(1)
->withQueryString();
and you can check the reuqest data if you faced any issue by dd(request()->get('query'));
put it into index function and before your conditions

Related

Laravel - ToDateString() Behaves abnormally on Live Server

In my Laravel-5.8, I have this code:
Controller
public function index()
{
$userCompany = Auth::user()->company_id;
$leaverequests = HrLeaveRequest::where('company_id', $userCompany)
->orderBy('created_at', 'desc')
->get();
$incompleteCount = $leaverequests->filter(function ($item) {
return (
$item->leave_status == 2 ||
$item->leave_status == 3 ||
$item->leave_status == 4
);
})
->count();
$currentstatus = HrLeaveRequest::select('leave_status')
->where('is_resumption_activated', 1)
->whereIn('leave_status', array(3, 4))
->where('resumption_date', '<=', Carbon::now()->toDateString())
->orderBy('created_at', 'DESC')
->first();
return view('leave.employee_leave_requests.index')
->with([
'leaverequests' => $leaverequests,
'incompleteCount' => $incompleteCount
])
->with('currentstatus', $currentstatus);
}
Model:
protected $dates = [
'resumption_date',
];
View
<div class="panel-heading clearfix">
<div class="container-fluid">
#can('leave_request_create')
#if (! $leaverequests->count() || $currentstatus)
<div style="margin-bottom: 10px;" class="row">
<div class="col-lg-12">
<a class="btn btn-info" href="{{ route("leave.employee_leave_requests.create") }}">
Add Leave Request
</a>
</div>
</div>
#elseif (! $currentstatus)
<div style="margin-bottom: 10px;" class="row">
</div>
#endif
#endcan
</div>
</div>
The Purpose is to make the "Add Leave Request" when the condition is fulfilled. I tested it on my Windows Local System, and it works fine.
But when I deployed to Linux Ubuntu server, the "Add Leave Request" remains hidden even when the condition is fulfilled.
But when I removed this code:
where('resumption_date', '<=', Carbon::now()->toDateString())
from the Linux server, it becomes visible (it works).
PHP Version for both local sytem and Ubuntu server is PHP-7.3.
How do I get this resolved.

Display only if query is found via search in Laravel using php

I have referral code search box that query referral codes. this code must be available before user can register. So basically on Auth.register I have two boxes, firs t box holds the referral code search box and the other one is the registration box. My goal is to hide first the registration box and appear only if the code has found.
RegisterController
public function index(Request $request)
{
$keyword = $request->get('search');
$referral = Referral::where('code', 'LIKE', '%'.$keyword.'%')->get();
if (count ( $referral ) > 0)
return view ( 'Auth.register')->withDetails ( $referral )->withQuery ( $keyword );
else
return view ( 'Auth.register')->withMessage ( 'The code you provided is not existing.' );
}
register.blade.php
<!-- THIS IS THE FIRST BOX THAT HOLDS THE CODE SEARCH BOX -->
<div class="card mx-4">
<div class="card-body p-4">
<h1>Referral Code</h1>
<p class="text-muted">Please provide the referral code given to you by your collector</p>
#if(isset($message))
<div class="alert alert-success">
{{ $message }}
</div>
#endif
{!! Form::open(['method' => 'GET', 'url' => '/register', 'class' => 'form-inline my-2 my-lg-0', 'role' => 'search']) !!}
<div style="width: 100%;">
<input type="text" class="form-control" name="search" style="width: 100%;" placeholder="Enter your referral code here!">
</div>
<div style="width: 150px; margin: auto; margin-top: 20px; ">
<button class="btn btn-success btn-default" type="submit">
<i class="fa fa-search"></i> Check Availability
</button>
</div>
{!! Form::close() !!}
</div>
</div>
<!-- THIS IS THE 2ND BOX THAT HOLDS THE REGISTRATION FORM -->
#if(isset($details))
<div class="card mx-4">
<div class="card-body p-4">
#foreach($details as $code)
#if($code->status==0)
<h2>Code is available</h2>
#else
<h2>Code is already taken</h2>
#endif
#endforeach
... the rest of registration form ...
</div>
</div>
#endif
My problem now is, the #details is displaying the current rows of "Referrals"
Is there a way that query from this line,
$referral = Referral::where('code', 'LIKE', '%'.$keyword.'%')->get();
should only display if the result is match from $keyword?
because currently the page is look like this
Thanks!
I think you want something like to match the keyword against your database. So instead of partial matching use exact matching.
public function index(Request $request)
{
$keyword = $request->get('search');
$referral = Referral::where([
['code', $keyword],
['status', 0]
])->first();
if ($referral)
return view ( 'Auth.register')->withDetails ( $referral )->withQuery ( $keyword );
else
return view ( 'Auth.register')->withMessage ( 'The code you provided does not exist or already used.' );
}
And in view you need not to use the following lines.
#foreach($details as $code)
#if($code->status==0)
<h2>Code is available</h2>
#else
<h2>Code is already taken</h2>
#endif
#endforeach
Just add your registration form after #if(isset($details)).
Its weird how you are doing this. You can use AJAX to do it in a single page

Working with whereDoesntHave() in Laravel 5.4

How do I implement a scope where in the user will claim a reward on a specific level and once they claim their rewards, the reward field will no longer display the reward that they have claimed. So for example:
The user is on level 20, on his reward panel, there are 3 available rewards to be claimed, level 10, 15 and 20. So if the user claimed the level 10 reward, it will no longer display on the panel except for level 15 and 20 rewards.
Here is the code for the blade:
#foreach(App\LevelRewards::getRewards()->get() as $rewards)
#if(Auth::user()->level >= $rewards->level_required || Auth::user()->level == $rewards->level_required)
#if(App\ClaimReward::claimLevel()->get())
<div class="col-lg-2 col-md-3 col-sm-6 col-xs-6" style="margin: 5px 0px;">
<div class="hovereffect">
<a href="#" class="d-block mb-4 h-100">
<input type ="hidden" name="id" value="{{$rewards->id}}"/>
<img class="img-responsive" src="{{asset('rewards_img/'.$rewards->picture)}}" alt="">
</a>
<div class="overlay">
<h2 style="font-size: 14px;">{{$rewards->details}}</h2>
#if($rewards->type == 'physical')
<button type="button" class="btn btn-success btn-sm" data-toggle="modal" data-target="#claimPhysical" data-details="{{$rewards->details}}" data-id="{{$rewards->id}}" data-level="{{$rewards->level_required}}" data-physical="{{$rewards->item_name}}">
CLAIM
</button>
#else
<button type="button" class="btn btn-success btn-sm" data-toggle="modal" data-target="#claimDigital" data-id="{{$rewards->id}}" data-level="{{$rewards->level_required}}" data-physical="{{$rewards->item_name}}">
CLAIM
</button>
#endif
</div>
<div style="background: #2d2d2d; padding: 9px;">
<span class="credits_top">Required Level: <span>{{$rewards->level_required}}</span></span>
<p>{{$rewards->item_name}}</p>
</div>
</div>
#endif
#endif
#endforeach
And this is the code for the model ClaimReward model:
public function scopeClaimLevel2($query)
{
return $query->join('level_rewards','level_rewards.id','=','claim_rewards.reward_id')->select('level_rewards.*');
}
Any links and source of information regarding this question will be highly appreciated. Thank you.
Edit: I tried;
public function scopeClaimLevel($query)
{
return $query->join('claim_rewards','claim_rewards.reward_id','=','level_rewards.id')->select('level_rewards.*');
}
public function scopeGetRewards($query)
{
return $query
->join('claim_rewards','claim_rewards.reward_id','=','level_rewards.id')
->whereDoesntHave('claimLevel', function (Builder $query) {
$query->where('claim_rewards.status', '=', '0');
})
->select('level_rewards.*');
}
But it says
Call to undefined method Illuminate\Database\Query\Builder::getRelated()'
add another table that will hold rewards thats user already claimed,
and in the foreach check if this reward id exists in this user claimed rewards,
if not so show it and if yes so skip it.
the table will hold 2 fields:
1) user_id
2) rewards_id
regarding the comments above,
and after your edit to what you tried,
looks like the order of the query is wrong... put whereDoesntHave before the select,
and change to implementation of it as wrote in Laravel documentation example.
try this:
public function scopeClaimLevel2($query)
{
return $query
->join('claim_rewards','claim_rewards.reward_id','=','level_rewards.id')
->whereDoesntHave('claim_rewards', function (Builder $query) {
$query->where('status', '=', '0');
})
->select('level_rewards.*');
}
edit:
try to change the join, as wrote here: https://laravel.com/docs/5.4/queries#joins
build the join and in it's function set how to join and where status=0
return $query
->join('claim_rewards', function ($join) {
$join->on('claim_rewards.reward_id', '=', 'level_rewards.id')->where('status', '=', '0');
})
->select('level_rewards.*');

Laravel search not print the results

I have search box for my Laravel project it seems working because after request I'll get http://project.dev/search?q=fifth but nothing prints in blade template.
here is my SearchController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
use Illuminate\Support\Facades\Input;
use Carbon\Carbon;
class SearchController extends Controller
{
public function index() {
$countTodayOrders = Post::whereRaw('Date(created_at) = CURDATE()')->count();
$yesterday_posts = Post::whereRaw('Date(created_at) = DATE_ADD(CURDATE(), INTERVAL -1 DAY)')->count();
$weekly_posts = Post::whereBetween( 'updated_at', [Carbon::today()->startOfWeek(), Carbon::today()->endOfWeek()] )->count();
$monthy_posts = Post::whereRaw('MONTH(created_at) = ?', Carbon::today()->month)->count();
$q = Input::get('q');
$posts = Post::where('title','LIKE','%'.$q.'%')->orWhere('slug','LIKE','%'.$q.'%')->get();
if(count($posts) > 0)
return view('theme.search', compact('posts', 'countTodayOrders', 'yesterday_posts', 'weekly_posts', 'monthy_posts'))->withQuery ( $q );
else return view ('theme.index')->withMessage('No Details found. Try to search again !');
}
}
Here is my search form
<!-- search box -->
<form action="/search" method="get" role="search">
<div class="input-group">
<input type="text" class="form-control" name="q" placeholder="Search users"> <span class="input-group-btn">
<button type="submit" class="btn btn-default">
<span class="glyphicon glyphicon-search"></span>
</button>
</span>
</div>
</form>
<!-- search box -->
Here is my routes
Route::any('/search', ['uses' => 'SearchController#index', 'as' => 'search.index']);
Here is my blade
#extends('layout.app')
#section('content')
<div class="col-md-9 technology-left">
<div class="tc-ch wow fadeInDown" data-wow-duration=".8s" data-wow-delay=".2s">
#if(isset($details))
<p> The Search results for your query <b> {{ $query }} </b> are :</p>
<h2>Sample User details</h2>
<table class="table table-striped">
<thead>
<tr>
<th>Post</th>
</tr>
</thead>
<tbody>
#foreach($posts as $post)
<tr>
<td>{{$post->name}}</td>
</tr>
#endforeach
</tbody>
</table>
#endif
</div>
</div>
#endsection
where is my mistake?
Update
Now I have search box which is work and show data with pagination but when i search for example for word sample which i have 3 posts with that title in first page of results I'm getting results like this:
first page
But when i go to second page everything changes!
second page
Why?
Ok guys i got it thanks, the issue was withQuery method as i used compact i shouldn't use with i just added it to `compact and now it's working. but what about counting the results? how can i pass the number of founded result in blade?

Anchor tags for search results in Laravel 4

I've created a search that is querying multiple tables in a database. I'm trying change the href for each result, but obviously they have different routes/controllers. I added a custom attribute in the query:
$enterprise = DB::table('enterprise')
->selectRaw("'enterprise.show' as link")
->where('name', 'LIKE', '%' . $term . '%')
->orWhere('description', 'LIKE', '%' . $term . '%');
$entertainment = DB::table('entertainment')
->selectRaw("'entertainment.show' as link")
->where('name', 'LIKE', '%' . $term . '%')
->orWhere('description', 'LIKE', '%' . $term . '%');
Which works when I union the queries with the rest. I then have a foreach loop in my view:
#foreach($results as $r)
<div class="col-lg-3" style="padding-top: 20px">
<div class="hpanel">
<div class="panel-body text-center h-200">
<a style="color: #3c763d" href="{{route($r->link, $r->id)}}">
<h4 class="font-extra-bold no-margins text-success">{{Str::limit($r->name, 15)}}</h4></a>
<small>{{ Str::limit($r->description, 50) }}</small>
</div>
<div class="panel-footer">
<i class="fa fa-gbp"><p style="display: inline"> {{$r->cost}}</p></i>
</div>
</div>
</div>
#endforeach
But this gives me undefined property $r->id. So, I add in another select to my controller ->select('id', 'name' et al) and then I get undefined property $link.
I have no idea how to link each result to their relevant route/controller. How can I achieve this?
I'm pretty sure it's because you need to add the other columns in the select portion of your eloquent query.
Something like:
selectRaw("id, name, enterprise.show as link")

Categories