I have a table full of sponsorship kids and I would like the users to filter them by Location, Gender and more. Just starting out with those 2 for the moment. Will add more filters later.
On my Filter form
<form action="{{ route('child-sponsorship-filter') }}" method="get">
@csrf
Location
<select name="location">
<option value="">No Preference</option>
@foreach ($country as $c)
<option value="{{$c->country_name}}">{{$c->country_name}}</option>
@endforeach
</select>
Gender
<select name="gender">
<option value="">No Preference</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
<button type="submit">Filter Results</button>
</form>
/// Begin Displays All and Filtered sponsor children
@foreach ($sponsorKid as $sk)
...
@endforeach
On my KidController
public function index(){
$country = DB::table('countries')->orderBy('country_name')->get();
$sponsorKid = Kid::orderBy('first_name')->get();
return view('child-sponsorship.index',compact('sponsorKid','country'));
}
public function filter(Request $request){
$location = $request->location;
$gender = $request->gender;
// $filter = [$location->location, $gender->gender];
//dd($location);
$country = DB::table('countries')->orderBy('country_name')->get();
if(empty($gender) && empty($location)){
$sponsorKid = Kid::orderBy('id')->get();
}elseif(!empty($gender) && !empty($location)){
$sponsorKid = DB::table('kids')->where('current_country', $location)->where('gender', $gender)->orderby('id')->get();
}elseif($gender != true){
$sponsorKid = DB::table('kids')->where('current_country', $location)->orderby('id')->get();
}elseif($location != true){
$sponsorKid = DB::table('kids')->where('gender', $gender)->orderby('id')->get();
}else{
$sponsorKid = Kid::orderBy('id')->get();
}
return view('child-sponsorship.index',compact('sponsorKid','country'));
}
Kids Table
+----+------------+--------+-----------------+
| id | first_name | gender | current_country |
+----+------------+--------+-----------------+
| 1 | Emma | Female | Haiti |
| 2 | Lea | Female | Nepal |
| 3 | Matthew | Male | India |
| 4 | Andrew | Male | Nepal |
| 5 | CHRIS | Male | Haiti |
+----+------------+--------+-----------------+
Countries Table
+----+--------------+
| id | country_name |
+----+--------------+
| 1 | Haiti |
| 2 | India |
| 3 | Nepal |
+----+--------------+
Routes in use
Route::get('/child-sponsorship','KidController@index')->name('child-sponsorship');
Route::get('/child-sponsorship/filter','KidController@filter')->name('child-sponsorship-filter');
Do to the @csrf
in the form I get the token in the URL. How can I remove that? http://xxxxxx.oo/child-sponsorship/filter?_token=jqFSC7tTmHuZ1tL8Dzz1LzNQNv5F2pOUrAa5uzs2&location=Haiti&gender=Male
After selecting a filter, For example: Location, Haiti
. I can't seem to get the current filter to stay in place on the select box after page refresh. It returns back to it's default state after page refresh. (Do I need a 3rd route?)
Can someone show me how I can update the filters via ajax without the page refresh.
Is there a better way to filter the query rather than using a ton of if statements?
Any help would be appreciated!
Okay I'm getting closer I think.
Routes:
Route::get('/child-sponsorship','KidController@index')->name('child-sponsorship');
Route::get('/child-sponsorship/filter','KidController@filter')->name('child-sponsorship-filter');
Index View (Show filter form and sponsor children)
<form id="myForm">
<label>Location</label>
<select id="location" name="location">
<option value="">No Preference</option>
@foreach ($country as $c)
<option value="{{$c->country_name}}">{{$c->country_name}}</option>
@endforeach
</select>
<label>Gender</label>
<select id="gender" name="gender">
<option value="">No Preference</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
<button id="ajaxSubmit">Filter Results</button>
</form>
@foreach ($sponsorKid as $sk)
////.......
@endforeach
-----------------------------------------------------
// JS
@section('filter_js')
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script>
jQuery(document).ready(function(){
jQuery('#ajaxSubmit').click(function(e){
e.preventDefault();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
}
});
jQuery.ajax({
url: "{{ route('child-sponsorship-filter') }}",
method: "get",
data: {
location: jQuery('#location').val(),
gender: jQuery('#gender').val(),
},
success: function(result){
console.log(result);
}});
});
});
</script>
@endsection
According to my Debug bar tool I'm getting the correct query:
select * from `kids` where `current_country` = 'Nepal' and `gender` = 'Female' order by `id` asc
But it is NOT showing correctly on the page....? I'm also getting the correct path in my console:
jquery.min.js:19 XHR finished loading: GET "http://xxxxxx.oo/child-sponsorship/filter?location=Nepal&gender=Female".
What am I doing wrong here?
These are my 2 functions in KidController
(index and filter)
public function index(){
$country = DB::table('countries')->distinct('country_name')->orderBy('country_name')->get();
$sponsorKid = Kid::orderBy('first_name')->get();
return view('child-sponsorship.index',compact('sponsorKid','country'));
}
public function filter(Request $request){
$location = $request->location;
$gender = $request->gender;
$country = DB::table('countries')->orderBy('country_name')->get();
if(empty($gender) && empty($location)){
$sponsorKid = Kid::orderBy('id')->get();
}elseif(!empty($gender) && !empty($location)){
$sponsorKid = DB::table('kids')->where('current_country', $location)->where('gender', $gender)->orderby('id')->get();
}elseif($gender != true){
$sponsorKid = DB::table('kids')->where('current_country', $location)->orderby('id')->get();
}elseif($location != true){
$sponsorKid = DB::table('kids')->where('gender', $gender)->orderby('id')->get();
}else{
$sponsorKid = Kid::orderBy('id')->get();
}
return view('child-sponsorship.index',compact('sponsorKid','country'));
}
I'm returning the same view as I don't want it to refresh to a new page.