How to create filter with easy way in laravel 8 using controller and checkbox - laravel

I am creating filter for the products, I tried using jquery for this before but I am not able to fix the pagination in laravel. So, I am trying this to fix the pagination as well as reduce the database query, bcoz in jquery everytime I click on any category or sub category, then it hits the database so the number of execution was more, So I replace the jquery and trying to use the button to do the same. But stuck with the array.
Can anyone help me with this?
$category = ["p1","p2","p3"];
$sub_category = ["c1","c2","c3","c4"];
$data = [];
$count = 0;
foreach ($cate as $category){
$data2 =[];
$count1 = 0;
foreach ($sub_cate as $sub){
$data2[] = [
'sub_category_id' => $category.$count1++,
'sub_category' => $sub,
'url' => $category.'|'.$sub
];
}
$data[] = [
'category_id' => 'category_'.$count++,
'category' => $category,
'sub_category' => $data2
];
}
In blade file :
#foreach($filters as $filter)
<div class="custom-control custom-checkbox mb-2">
<input type="checkbox" class="custom-control-input category_filter1" id={{$filter["category_id"]}} name="category_filter[]" value="{{$filter["category"]}}">
<label class="custom-control-label w-100" for="{{$filter["category_id"]}}">{{$filter["category"]}}</label>
#foreach($filter["sub_category"] as $sub)
<div class="custom-control custom-checkbox mb-2">
<input type="checkbox" class="custom-control-input category_filter1" id={{$sub["sub_category_id"]}} name="sub_category_filter[]" value="{{$sub["url"]}}">
<label class="custom-control-label w-100" for="{{$sub["sub_category_id"]}}">{{$sub["sub_category"]}}</label>
</div>
#endforeach
</div>
#endforeach
After using this code I am getting this type of data :
{"category_filter":["p1","p2"],"sub_category_filter":["p1|c1","p1|c2","p1|c3","p1|c1"]}
So basically the array structure is like this :
For now everything looks nice but, When I try to combine the array into once then it look some time to sort and rearrange itself, So it there any easy way to this, Each time I change the filters it will take time and then it fetch result from the database. For some reason I thought that URL which is custom made will help me but it only taking us to the wrong direction.

apply condition in conrtoller like this
if($request->input('category_filter') == "p1"){
if($request->input('sub_category_filter') == "p1|c1"){
... do your code as per your need
}
}
I share Sample Example:
assume I want to filter data like All, approved, pending, decline... then I write script in controller like this
if($request->input('filtertype')){
$filtertype = $request->input('filtertype');
if($filtertype == "All"){
$deals = Deal::orderBy('updated_at', 'desc')->get();
}else{
$deals = Deal::where('deal_isApproved', '=', $filtertype)
->orderBy('updated_at', 'desc')->get();
}
}
return view('admin.deals.index',compact('deals'));

Related

Laravel : how to get $payment_gateway value

I'm trying to create a feature where, when i create a new booking i can choose the payment method like via xendit or transfer. But when i tried to submit the output of the payment method is still offline payment because of this code {{$row->gatewayObj ? $row->gatewayObj->getDisplayName() : ''}} , and not xendit. How do i fix this??
The Controller :
public function create(Request $request){
// $this->checkPermission('news_create');
$allServices = get_bookable_services();
$whatsAppBookableServices = ["art", "food", "gear", "car", "hotel"];
$payment_gateway = ["xendit", "offline payment"];//tambahan Nicho
$row = new BookingOffline();
$row->fill([
'status' => 'publish',
]);
$data = [
// 'categories' => NewsCategory::get()->toTree(),
'row' => $row,
'breadcrumbs' => [
[
'name' => __('Report'),
'url' => 'admin/module/report/booking'
],
[
'name' => __('Add Booking By WA'),
'class' => 'active'
],
],
'bookableServices' => array_keys($allServices),
'whatsAppBookableServices' => $whatsAppBookableServices,
'payment_gateway' => $payment_gateway,//tambahan Nicho
];
return view('Report::admin.booking.create', $data);
}
The Blade file :
<td>
{{$row->gatewayObj ? $row->gatewayObj->getDisplayName() : ''}}
</td>
The gatewayObj :
function get_payment_gateway_obj($payment_gateway)
{
$gateways = get_payment_gateways();
if (empty($gateways[$payment_gateway]) or !class_exists($gateways[$payment_gateway])) {
return false;
}
$gatewayObj = new $gateways[$payment_gateway]($payment_gateway);
return $gatewayObj;
}
There are still missing pieces to the puzzle, so I cannot provide you with a code snippet to implement.
However, I think you should be able to diagnose it this way:
Check your controller.
Do a die-dump of the $data just above the line containing return view.... Like so: dd($data['payment_gateway'])
Then refresh the page in your browser and see if the $data object is exactly how you want it. The value should be ["xendit", "offline payment"].
Check your form
I suppose you have a form element like a <select></select>, which is iterating over the values of the $data['payment_gateway'] array. If you do not have this, how are your users choosing between the payment options?
Next, make sure that each iteration of payment gateway is being submitted properly. YOu did not include the snippet that handles form submission, but if you're using a <select> element, the options each need to be submitted with a value.
If we hardcode the select, you will have something like this:
<select name="payment_gateway">
<option value="xendit">Xendit</option>
<option value="offline">Offline Payment</option>
</select>
So when the server receives this form information, it knows the exact value of payment gateway to use. Dynamically, it could look like this:
<select name="payment_gateway">
#foreach($data['payment_gateways'] as $gateway)
<option value="{{ $gateway }}">{{ $gateway }}</option>
#endforeach
</select>
Intercept the request and check that your payment_gateway is being submitted properly.
Go to the controller method that handles your form, and do something like dd($request->all())
Then inspect the value of payment_gateway.

Laravel Livewire 2.6: Indirect modification of overloaded element of Illuminate\Database\Eloquent\Collection has no effect

Based on https://laravel-news.com/livewire-v2-6-0, Livewire has supported deep model data binding. And I write the following codes to test the feature:
$details = new Collection([
new Detail(['quantity' => 10, 'amount' => 5]),
]);
$this->receive = new Receive;
$this->receive->setRelation('details', $details);
<div>
#foreach($receive->details as $index => $detail)
<input type="text" wire:model="receive.details.{{ $index }}.quantity" wire:key="receive.details.{{ $index }}.quantity">
#endforeach
</div>
When I changed the quantity, I got the following error:
Indirect modification of overloaded element of Illuminate\Database\Eloquent\Collection has no effect
But, if I query the receive from database, it works fine.
$this->receive = Receive::find(1);
Any idea what could be happening here? Any help or guidance is much appreciated.

Laravel Validating Arrays Select fields

Laravel easily validates array based form input fields
<input name='input_name[0][0]">
<input name='input_name[0][1]">
with
'input_name.* = 'required',
https://laravel.com/docs/5.5/validation#validating-arrays
But how can I validate array based select fields?
I have a form where customer info is added, user has to choose the customer's gender and it's possible to add infinite number of customer.
So i have a select for 1 customer:
<select name="gender[0]">
<option selected="selected" disabled="disabled" hidden="hidden" value="">Gender</option>
<option value="Male">Male</option>
<option value="Female">Female</option></select>
and then
<select name="gender[1]">...
<select name="gender[N]">
When I set the rule as:
'gender.*' => 'required'
It doesn't recognize an 'unchoosen' select-box as an error....
But if I update validation rules to:
'gender[0]'=>'required'
'gender[1]'=>'required'
'gender[N]'=>'required'
It works absolutely fine... (by "it works", I mean that it returns a mistake "Gender field is required").
So, apparently Laravel has some problems with array based select names.
Appreciate any help!
public function rules() {
$rules = [];
$gender = $this->input('gender');
foreach ($gender as $index => $item) {
$rules["gender.{$index}"] = 'required';
}
return $rules;
}
I've decided o answer the question myself.
1) First solution is to make the first "placeholder" option not disabled (as was in my case, see above - it's because I use LaravelCollective and they have it by default):
<select name="gender[0]">
<option selected="selected" hidden="hidden" value="">Gender</option>
<option value="Male">Male</option>
<option value="Female">Female</option></select>
When you remove 'disabled' from option-1 of your select then it sends ' ' when posting (instead of sending nothing with 'disabled'). So it sends
gender[0] = '';
gender[1] = '';
etc...
Actually, if you have a lot of gender[N] (or maybe other array based selects) I think it's the neatest solution.
2) Second solution is provided below by omadonex:
public function rules() {
$rules = [];
$gender = $this->input('gender');
foreach ($gender as $index => $item) {
$rules["gender.{$index}"] = 'required';
}
return $rules;
}
in this case you'll have a separate rule for every array-based select and it will work (see why in the end of my topicstarter-post). I prefer this solution less than 1st one because you'll have a long list of "gender"-rules if you have a lot of ...
3) Also I've undertood why 'gender[0]'=>'required'
works
and 'gender.*' => 'required'
does not
for array based selects like <select name=gender[0]>
It's kind of obvious if you think about it: when POSTING select tag with first option (a placeholder) being disabled, as in my example above:
<option selected="selected" disabled="disabled" hidden="hidden" value="">Gender</option>
the $POST sends nothing....
So if Laravel's validation rule is 'gender[0]'=>'required' Laravel "thinks": "OKAY, I've received no "gender[0]", but I know what is required exactly ("gender[0]", of course) . I have to send a mistake because there is no "gender[0]".
But if rule is 'gender.*' => 'required' and Laravel get's no input of "gender" kind, then it also doesn't know what EXACTLY is required ('gender.*' may mean gender[0]... gender [12345] ... gender[anything]). Laravel can't send a mistake, because infinite number of gender[...] is missing, so he simply omits it....
PS. If you work with LaravelCollective forms of newer versions, they create placeholder "disabled" by default. Here is a macro to avoid it.
{!!
Form::macro('selectNonDisabled', function($value, $placeholder, $array, $disabled=null, $class=null) {
$select = "<select class='form-control $class' $disabled name='$value'>";
$select .= "<option selected='selected' hidden='hidden' value=''>$placeholder</option>";
foreach ($array as $key => $value) {
$select .= "<option value='$key'>$value</option>";
}
$select .= "</select>";
return $select;
});
!!}

search form using laravel shows 'Call to a member function getNumCommentsStr() on a non-object'

i have made a search bar using laravel, but it did not succeed. it shows the error as said below. And it seems that something wrong with my post object. But i do not know where.
source code as follows, thanks for helping.
//the searchController for seach code
public function search(){
$keyword = Input::get('keyword');
if(empty($keyword)){
return Redirect::route('/');
//->with('message',array('type' => 'alert', 'content' => '不能为空'))
}
$posts = Post::where('content', 'like', '%'.$keyword.'%')->orderBy('created_at', 'desc')->paginate(10);
$tags = Tag::where('count','>','0')->orderBy('count','desc')->orderBy('updated_at', 'desc')->take(20)->get();
return Redirect::route('searchResults')->with('posts', $posts->toArray())->with('tags',$tags);
}
public function searchResults(){
return View::make('frontend.search.search',['posts' => Session::get('posts'),'tags' => Session::get('tags')]);
}
//search bar route
Route::get('/searchResults', array(
'uses' => 'SearchController#searchResults',
'as' => 'searchResults'
));
Route::post('/search', array(
'before' => 'csrf',
'uses' => 'SearchController#search',
'as' => 'search'
));
//search from
{{ Form::open(array('url'=>'/search','method' => 'post','class'=>''))}}
{{ Form::token()}}
<label for="docSearch">
<i class="fa fa-search"></i>
</label>
<div class="searchInput">
{{Form::text('keyword', '', array('class'=>'docsSearch', 'placeholder'=>'搜索论坛动态...'))}}
{{ Form::submit('提交',array('class'=>''))}}
{{Form::close()}}
//now i just wanna to get it like this:
#if(!$posts)
{{'<section class="oneQuestion">sorry,no content...</section>'}}
#else
#foreach($posts as $post)
<section class="oneQuestion">
<div class="askResult">
<!-- <i class="fa fa-question notSolved"></i>
<i class="fa fa-check solved" style="display:none;"></i> -->
#if($post->getNumCommentsStr() == 0)
<a href="{{URL::route('viewPost', array('id' => $post->id))}}#reviews" class="notSolved"><span class="post_comment_Num">{{$post->getNumCommentsStr()}}</span>
<span> 回答</span>
</a>
#else
<a href="{{URL::route('viewPost', array('id' => $post->id))}}#reviews" class="solved"><span class="post_comment_Num">{{$post->getNumCommentsStr()}}</span>
<span> 回答</span>
</a>
#endif
</div><!--
--><div class="titlePart">
<span>
{{$post->user->username}}
{{$post->created_at->diffForHumans()}}
</span>
<a href="{{ URL::route('viewPost', $post->id)}}">
{{-- {{ substr($post->content,0,200) }}... --}}
{{$post->title}}
</a>
<div class="tagWrapper">
#foreach ($post->tags as $tag)
<span class="askTag" title="">{{$tag->name}} </span>
#endforeach
</div>
</div>
</section>
#endforeach
#endif
<div class="forumLink">
{{$posts->links()}}
</div>
//it showed me an error:
**Call to a member function getNumCommentsStr() on a non-object**
and my getNumCommentsStr like:
public function getNumCommentsStr()
{
$num = $this->reviews()->count();
// if($num == 1){
// return "1";
// }
return $num;
}
code seems a lot but i wanna to make it clear so you can find any errors. Thanks again.
Edit 2
Thanks for NightMICU's suggest and I change
Redirect::route('searchResults')->with('posts', $posts->toArray())->with('tags',$tags);
to the following:
Redirect::route('searchResults')->with('posts')->with('tags',$tags);
THE result is without any alert any more, it just shows: sorry, no content...
And did not show any search result, any problem? Thanks
EDIT TWO
//delete the searchResult method, all in one search method so that i can return the view in right in the search method.
public function search(){
$keyword = Input::get('keyword');
if(empty($keyword)){
return Redirect::route('developer');
//->with('message',array('type' => 'alert', 'content' => '不能为空'))
}
$posts = Post::where('content', 'like', '%'.$keyword.'%')->orderBy('created_at', 'desc')->paginate(10);
$tags = Tag::where('count','>','0')->orderBy('count','desc')->orderBy('updated_at', 'desc')->take(20)->get();
return View::make('frontend.search.search',['posts' => $posts,'tags' => $tags]);
}
EDIT 3
there are two questions exsiting here.
ONE is that when i change to that ,it can output the result but all the result the database has. Not the keyword results.
Two is that when there are extra page, once i open the link http://localhost/html5lav/public/search?page=2, it just show an error:
No query results for model [Post].
The initial issue most likely has to do with the unusual way you are displaying the search results; by passing the Eloquent collections via session to another method, only to display the View. You were also converting the Post Eloquent collection to a regular array with ->toArray(), pagination requires a collection rather than an array.
The solution for that part:
public function search(){
$keyword = Input::get('keyword');
if(empty($keyword)){
return Redirect::route('/');
//->with('message',array('type' => 'alert', 'content' => '不能为空'))
}
$posts = Post::where('content', 'like', '%'.$keyword.'%')->orderBy('created_at', 'desc')->paginate(10);
$tags = Tag::where('count','>','0')->orderBy('count','desc')->orderBy('updated_at', 'desc')->take(20)->get();
return View::make('frontend.search.search')->with('posts', $posts)->with('tags', $tags);
}
After taking care of the initial issue, you reported that the pagination links are not working as expected - you click on Page 2 and do not have any Post results. If the route for the page where the user inputs a search term is also /search, there is a conflict. Instead, change the route that the search form posts to, perhaps /searchResults (which then loads the results using the search method). You may also want to consider using a GET rather than POST request, allowing users to bookmark their search results or share a link.
Regarding the issue of displaying all of the entries from the posts table, you need to review MySQL raw queries in Laravel. Swing by the documentation and look them up.

where to add- class="required" (jquery validation) in form_dropdown?

I have a dropdown list which is being populated from database. It is working fine but in the form_dropdown in the view file, I want to add class="required" for validating the dropdown using Jquery. I have tried to make it work but as it turned out it won't work. Would you please kindly help me where exactly to put the class="required" - and make the jquery validation work?
Thanks in Advance
I have this in my controller
// To get the batch name
$this->load->model('dropdown_batchlist');
$data['dropdown_batchlist']= $this->dropdown_batchlist->dropdown_batchlist();
this in my model-
function dropdown_batchlist() {
$this->db->select('batchname, batchid');
$records=$this->db->get('batch');
$data=array();
// add it here as the first item in the array,
// assuming you don't have a $row->batchid of 0 in your results.
$data[0] = 'SELECT';
foreach ($records->result() as $row)
{
$data[$row->batchid] = $row->batchname;
}
return ($data);
}
And this in my view file
<?php echo form_dropdown('batchid', $dropdown_batchlist,'', 'class="required"' ); ?>
The Problem is Solved
I have figured out the problem. The view file was okay, all I had to do is replace $data[0] = 'SELECT'; with
$data[' '] = 'SELECT';
Thanks
Try setting the attributes using an associative array:
$attributes = array(
'name' => 'batchid',
'class' => 'required',
'options' => $dropdown_batchlist
);
echo form_dropdown($attributes);

Resources