How to use json response with relationship - laravel

I want to fetch data from the pivot table platform_user. I am able to get the ID of the user using ajax. PLease see my code below.
Controller
public function show($id) {
$users_id = User::find($id);
$users_id->with('platforms')->where('id', $id)->get();
return response()->json($users_id);
}
Blade - I am using bootstrap modal to get the USER ID and NAME in pop modal. However, I need to fetch data for that USER ID related to the pivot table.
<select name="platform" id="platform" class="form-control">
#if(isset($users_id))
#foreach($users_id as $user_platform)
#foreach($user_platform->platforms as $platform)
<option value="{{$platform->id}}">{{$platform->title}}</option>
#endforeach
#endforeach
#endif
</select>
<script type="text/javascript">
$(document).ready(function() {
$('body').on('click', '#show_user', function () {
var userURL = $(this).data('url');
$.get(userURL, function (data) {
$('#removePlatformModal').modal('show');
$('#user_id').text(data.id);
$('#user_name').text(data.name);
})
});
});
</script>

Try using [whereHas]:
public function show($id) {
$users_id = User::find($id);
$users_id->whereHas('platforms', function($query) use ($user_id){
$query->where('id', $user_id);
})->get();
return response()->json($users_id);
}

Related

The data from input dropdown select2 is not fetch into datatables

I did a multiselect input dropdown using select2. However, I dont really sure how to fetch the data that I call from database in the dropdown so that I can view it in datatable. Here are my codes:
Script for input dropdown select2:
$('.ethnicity').select2({
placeholder: 'Select..',
ajax: {
url: '/select2-autocomplete-ajax_ethnicity',
dataType: 'json',
delay: 250,
processResults: function ($ethnicity) {
return {
results: $.map($ethnicity, function (item) {
return {
text: item.Bangsa_updated,
id: item.id,
}
})
};
Controller for input dropdown so it will select the input typed:
public function ethnicity(Request $request)
{
$ethnicity = [];
if($request->has('q')){
$search = $request->q;
$ethnicity = DB::table("user")
->select("id","ethnic")
->where('ethnic','LIKE',"%$search%")
->get();
}
return response()->json($ethnicity);
}
The above code only to select the data from database without fetch data to datatable.
The controller below to catch data into datatable (I used this for simple dropdown, however dont know how to change so it is useful for above input dropdown.
public function fnFilter(Request $request)
{
if(request()->ajax())
{
if(!empty($request->dataGender))
{
$data = DB::table('user')
->select('id', 'Fn', 'Ln')
->where('ethnic', $request->ethnicity)
->get();
}
else
{
$data = DB::table('user')
->select('id', 'Fn', 'Ln', 'Umur', 'Phone', 'Dob','St', 'Country','Zip','Ct','Jantina')
->get();
}
return datatables()->of($data)->make(true);
}
$dataName = DB::table('modified_dpprs')
->select('ethnic','Jantina')
->groupBy('ethnic')
->orderBy('ethnic', 'ASC')
->get();
return response()->json($dataName);
Blade is:
<select id="ethnicity" class=" ethnicity form-control select2-allow-clear" style="width:200px;" name="namaDUN" multiple >
<option value="">Select</option>
My idea is to put the result from controller function ethnicity into function fnFilters. But I dont know how can do it.
you can return response in select2 (controller function) required format
like
$final_array = [];
$ethnicity = DB::table("user")
->select("id","ethnic");
if ($request->search != '') {
$search = $request->search ;
$ethnicity=$ethnicity->where('ethnic','LIKE',"%$search%");
}
// loop the results to make response
foreach($ethnicity->get() as $key => $value):
$final_array[$key]['id'] = $value->id;
$final_array[$key]['text'] = $value->ethnic;
endforeach;
return ['results' => $final_array];
// function ends here
and select 2 tag in blade file like this
$('.ethnicity').select2({
placeholder: 'Select..',
ajax: {
url: '/select2-autocomplete-ajax_ethnicity',
minimumInputLength: 3,
data: function (params) {
var query = {
search: params.term,
page: params.page || 1
}
return query;
}
}
});

Two actions on a function in Laravel, possible?

I have 2 users roles in my application, admin and former.
The admin can create several formers...
If, I connect me with the ID 1 ? I retrieve the information of the former.
So, my function index() allows to retrieve id of the user
public function index()
{
if($has_role = auth()->user()->hasRole('admin')){
$formers = Former::first()->paginate(5);
return view('admin.formers.index', compact('formers'));
} else{
$formers = Former::where('email', Auth::user()->email)->paginate(5);
return view('admin.formers.index', compact('formers'));
}
}
Well, for the user admin, I would like to create a search bar...
I had created before a function index() and which worked
public function index(Request $req)
{
if ($req->search == "") {
$formers = Former::paginate(5);
return view('admin.formers.index', compact('formers'));
} else {
$validated = $req->validate([
'search' => 'alpha',
]);
$formers = Former::where('nom', 'LIKE', '%' . $validated['search'] . '%')->paginate(5);
$formers->appends($req->only('search'));
return view('admin.formers.index', compact('formers'));
}
}
Now, I would like to adapte my 2 actions in a function, is it possible according you?
Do you think that I can get the user_id and make a search bar in the same function?
Thank you
What I would do is the following:
Add one action which serves both roles with data.
Display the search only to admins, but ignore this fact on the server-side as it doesn't matter from a security perspective whether non-admins can search or not. They are limited to their result anyway.
Basically, this is achievable in the following way:
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
public function index(Request $request)
{
$user = $request->user();
$formers = Former::query()
->when($user->hasRole('admin') !== true, function (Builder $query) use ($user) {
$query->where('email', $user->email);
})
->when($request->has('s'), function (Builder $query) use ($request) {
$query->where('nom', 'like', '%'.$request->input('s').'%');
})
->paginate(5);
return view('admin.formers.index', compact('formers'))
->with('display_search', $user->hasRole('admin'));
}
You can then in your view simply use the $display_search variable to decide whether or not you want to display the search:
#if($display_search)
<form method="post" action="...">
<input type="text" name="s" placeholder="Type to search...">
</form>
#endif
I would create a policy with a search method:
public function search($user)
{
if ($user->isAdmin()) {
return true;
}
}
now you may just edit your blade
#can('search')
<form method="post" action="/search">
<input type="text" name="search" placeholder="Recherche...">
</form>
#endcan
If you want to give search access to other users as well, you only have to modify the policy.

Laravel Resource controller for filtering

I have a resource Controller for an API that I'm developing for displaying records that can be filtered by Type and Customer and I have the following methods that can get this data:
index
show -> requires an parameter (id)
Can I therefore put a request inside the index method for filtering all of the entries back or is it bad practise for doing this? My code looks like the following:
public function index()
{
$entries = \App\Ent::where(function($en) {
$request = app()->make('request');
if($request->has('type')) {
$en->where('type', '=', $request->get('type'));
}
if($request->has('customer')) {
$en->where('customer', '=', $request->get('customer'));
}
})->get();
dd($entries);
}
Filtering in Laravel is very simple and you don't need to do this. In your Ent model, define the following:
public function scopeFilter($query, $filters)
{
if( isset($filters['type']) ){
$query->where('type', '=', $filters['type']);
}
// keep going for all of your filters
}
And on your Controller index method you can:
public function index()
{
$entries = \App\Ent::filter(['type', 'customer'])->get();
dd($entries);
}
EDIT
To help you make more sense of this, let's filter Ent on the type column in the database.
Route:
Route::get('/ent', 'EntController#index');
Ent Model:
class Ent extends Model
{
public function scopeFilter($query, $filters)
{
if( isset($filters['type']) ){
$query->where('type', '=', $filters['type']);
}
}
}
Ent Controller:
class EntController extends Controller {
index()
{
$entries = \App\Ent::filter(['type'])->get();
return view('ent.index', compact('entries'));
}
}
Let's say for the sake of this example we are just going to put a form on the same blade template we are outputting our list:
#foreach( $entries as $entry )
<p>{{ $entry->type }}</p>
#endforeach
<form method="GET" action="/ent">
{{ csrf_field() }}
<input type="text" name="type" />
<input type="submit" value="Filter" />
</form>
So now, if I were to go into that form and type 'Foo Bar' and hit submit, you would get what would look something like this in SQL
SELECT * FROM Ent WHERE type='foo bar'
Or in other words, all Ent with the type column = 'foo bar'.
When I give a user the ability to type raw text in to filter, I like to give them the benefit of the doubt and use LIKE instead of =. So for example we would just change our scopeFilter method:
if( isset($filters['type']) ){
$query->where('type', 'LIKE', '%' . $filters['type'] . '%');
}
Another thing to note here, the filters[name] is the name of the <input> field, NOT the name of the column in your database. You target the column in the $query extension, NOT in the $filters array. See below example:
if( isset($filters["ent_type"] ){
$query->where('type', '=', $filters["ent_type"]);
}
On my form that would be
<input name="ent_type" type="text" />

Auto Completion Ajax laravel

Hello I need to do autocompletion to some cities i already have in my db
so my code is like this :
View
<input type="text" name="ville" id="ville" class="small" placeholder="Entrer la ville souhaité">
<script type="text/javascript">
$(function() {
$( "#ville" ).autocomplete({
source:'{!!URL::route('autocomplete')!!}',
minlength:1,
autoFocus:true,
select:function(e,ui)
{
$('#ville').val(ui.item.value);
}
});
});
</script>
Controller
class VilleController extends Controller
{
public function autocomplete(Request $request)
{
$term = $request->term;
$queries = DB::table('ville')
->where('libelle_ville', 'like', '%'.$term.'%')
->take(6)->get();
foreach ($queries as $query)
{
$results[] = ['id' => $query->id, 'value' => $query->libelle_ville]; //you can take custom values as you want
}
return response()->json($results);
}
}
Routes
Route::get('/autocomplete', array('as' => 'autocomplete', 'uses'=>'VilleController#autocomplete'));
It doesn't tells me that I have an error and it doesn't show me any completion either.
Debug json request with laravel is a bit difficult, I recommend you to download this package
https://github.com/ARCANEDEV/LogViewer
or manually open the laravel log in storage/logs/laravel.log and see whats happened
Thanks to Stack and EddyTheDove I found out that the error is that aucomplete is not a function so I have to remove the barkets and $function so it would be something like this in the script tag
<script type="text/javascript">
$( "#ville" ).autocomplete({
source:'{!!URL::route('autocomplete')!!}',
minlength:1,
autoFocus:true,
select:function(e,ui)
{
$('#ville').val(ui.item.value);
}
});
</script>

Username Availablity check in laravel 5 using ajax

On my view page if I am entering username after loader.gif is loading but I am not getting the result for username available or not.. pls give me any ideas...
This is my controller:
public function index()
{
return view('test/username');
}
public function username()
{
$username = Input::get('username');
$users = DB::table('user')
->where('username',$username)
->first();
if ($users !== null)
{
return true;
}
return false;
}
These are my routes:
Route::get('test/username', 'PageController#index');
Route::post('test/username', 'PageController#username');
This is my Blade template:
<html>
<head>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#username").change(function () {
$("#message").html("<img src='../images/loader.gif' /> checking...");
var username=$("#username").val();
$.ajax({
type:"post",
url: "{{ URL::to('test/username') }}",
data: {username:username},
success: function (data) {
if (data == 0) {
$("#message").html("<img src='../images/yes.png' /> Username available");
} else {
$("#message").html("<img src='cross.png' /> Username already taken");
}
}
});
});
});
</script>
</head>
<body>
<table>
<tr>
<td>Username</td>
<td>:</td>
<td>
<input type="text" name="username" id="username"/>
</td>
<td id="message"></td>
</tr>
</table>
</body>
</html>
In your routes you are not actually calling the username function declared in your controller but a name one, which doesn't exist. Try modifying your second route to:
Route::post('test/username', 'PageController#username');
There are a few issues with your code. First of all, you should only check for exact usernames instead of using LIKE, or this could match similar usernames. Start by updating your function to (comments in code):
public function username()
{
$username = Input::get('username');
$users = DB::table('user')
->where('username', $username) // exact matches only
->first(); // we only need one result
// instead of count, check that a valid result is returned
if ( $users !== null )
{
return true;
}
// else not required
return false;
}
You need to update your route to call the correct function:
Route::post('test/username', 'PageController#username');
Next, you need to update your JavaScript to correctly send the data to your PHP script. Update the data to:
data: { 'username': username },
If you still get errors, you may need to update the name() function to actually return JSON. You can do this using:
return \Response::json( true );

Resources