laravel datatable relationships - datatable

So in this app Drawing belongsTo Customer. I have datatable
<table id='drawing-table' class="table table-bordered table-hover">
<thead>
<tr>
<th>Drawing number</th>
<th>Customer</th>
</tr>
</thead>
</table>
which indicates $darwing->number and $customer->title. To load info I use yajra\Datatables\Datatables;.
Data is loaded with this JS method:
$(function () {
$('#drawing-table').DataTable({
processing: true,
serverSide: true,
ajax: '{{route('drawings.datatable')}}',
columns: [
{ data: 'number', name: 'number' },
{ data: 'customer.title', name: 'customer' },
]
});
});
And this Laravel method:
public function datatable()
{
$drawings = Drawing::select(array('drawings.id','drawings.number'));
return Datatables::of(Drawing::with('customer')->select('*'))->make(true);
}
QUESTIONS
How do I make datatable search window to work with $customer->title?
How do I display drawing number and customer title as link?

public function datatable()
{
//reference customer table
$drawings = DB::table('customers')
// join it with drawing table
->join('drawings', 'drawings.customer_id', '=', 'customers.id')
//select columns for new virtual table. ID columns must be renamed, because they have the same title
->select(['drawings.id AS drawing_id', 'drawings.number', 'customers.title', 'customers.id AS customer_id']);
// feed new virtual table to datatables and let it preform rest of the query (like, limit, skip, order etc.)
return Datatables::of($drawings)
->editColumn('title', function($drawings) {
return '' . $drawings->title . '';
})
->editColumn('number', function($drawings) {
return '' . $drawings->number . '';
})
->make(true);
}
Spent many hours trying to figure it out, hope it saves someone time.
http://datatables.yajrabox.com/fluent/joins

I'm not really sure about your first question. Datatables search window will search all the content. Do you want to make it specific to just 1 column?
To answer your second question, you can edit the column output. Try this
$drawings = Drawing::select(array('drawings.id','drawings.number'));
return Datatables::of(Drawing::with('customer')->select('*'))
->editColumn('customer', function($drawings) {
return '' . $drawings->customer . '';
})
->make(true);
Edit
To achieve the search that you want, You'll want to do something like this:
public function datatable(Request $request)
{
$drawings = Drawing::select(array('drawings.id','drawings.number'));
return Datatables::of(Drawing::with('customer')->select('*'))
->filter(function ($query) use ($request) {
if ($request->has('name')) {
$query->where('customer.customer_name', 'like', "%{$request->get('name')}%");
}
})
->editColumn('customer', function($drawings) {
return '' . $drawings->customer->customer_name . '';
})
->make(true);
}
Then, in your JS
$(function () {
$('#drawing-table').DataTable({
processing: true,
serverSide: true,
ajax: {
url: '{{route('drawings.datatable')}}',
data: function (d) {
d.name = $('input[name=name]').val();
}
},
columns: [
{ data: 'number', name: 'number' },
{ data: 'customer.title', name: 'customer' },
]
});
});
This is untested, but should achieve what you want.

you may also use elequent relationships with yajra here is the example code.
$sub_sectors = Sector::where('parent_id', '>', 0)->with('parent')->latest()->get();
$sub_sectors->each(function($sub_sectors){
$sub_sectors->sector = $sub_sectors->parent->title['en'];
});
in this example you can get sector against sub sector with each method you can get sector name and now you can display sector in your yajra table

Related

How to get the google map location by getting the latitude and the longitude values from the database in laravel 6.x

I have the latitude and the longitude values located in my database table, i have created a table where the users can filter the stores and the store location by selecting the values from the drop-down, i want to make a column which has a link for the users to click and find the store location in the google map. i have the latitude and the longitude values stored in my database, i don't know how can i add the link which will contain the latitude and the longitude value from the database and redirect the user to the google map and show the exact location,
Here's my Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\StoreFC;
class StoreFCController extends Controller
{
function index(Request $request)
{
if(request()->ajax())
{
if(!empty($request->filter_district))
{
$data = StoreFC::select('id','loc_type', 'loc_group', 'loc_code', 'location', 'location_2', 'status', 'latitude','logtitude','phone','address')
->where('location', $request->filter_district)
->where('loc_type', $request->filter_outlet)
->get();
}
else
{
$data = StoreFC::select('id','loc_type', 'loc_group', 'loc_code', 'location', 'location_2', 'status', 'latitude','logtitude','phone','address')
->get();
}
return datatables()->of($data)->make(true);
}
$outlet_name = StoreFC::select('loc_type')
->groupBy('loc_type')
->orderBy('loc_type', 'ASC')
->get();
$district_name = StoreFC::select('location')
->groupBy('location')
->orderBy('location', 'ASC')
->get();
return view('test.store-fc', compact('outlet_name','district_name'));
}
}
Here's my Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class StoreFC extends Model
{
protected $table = 'store_foodcity';
}
Here's my table
<table id="store_data" class="table table-bordered table-striped">
<thead>
<tr>
<th>ID</th>
<th>Outlet</th>
<th>Group</th>
<th>Code</th>
<th>Location</th>
<th>Location 2</th>
<th>Status</th>
<th>Latitude</th>
<th>Logtitude</th>
<th>Phone</th>
<th>Address</th>
</tr>
</thead>
</table>
Here's the script to fill the Data table
<script>
$(document).ready(function(){
fill_datatable();
function fill_datatable(filter_district = '', filter_outlet = '')
{
var dataTable = $('#store_data').DataTable({
processing: true,
serverSide: true,
ajax:{
url: "{{ route('store-foodcity.index') }}",
data:{filter_district:filter_district, filter_outlet:filter_outlet}
},
columns: [
{
data:'id',
name:'id'
},
{
data:'loc_type',
name:'loc_type'
},
{
data:'loc_group',
name:'loc_group'
},
{
data:'loc_code',
name:'loc_code'
},
{
data:'location',
name:'location'
},
{
data:'location_2',
name:'location_2'
},
{
data:'status',
name:'status'
},
{
data:'latitude',
name:'latitude'
},
{
data:'logtitude',
name:'logtitude'
},
{
data:'phone',
"render": function(data, type, row, meta) {
if (type === 'display') {
data = '<a class="gray" href="tel:' + data + '">' + data + '</a>';
}
return data;
},
name:'phone'
},
{
data:'address',
name:'address'
}
]
});
}
// $('#filter_outlet').on('change',function(){
$('#filter').click(function(){
var filter_district = $('#filter_district').val();
var filter_outlet = $('#filter_outlet').val();
if(filter_district != '' && filter_district != '')
{
$('#store_data').DataTable().destroy();
fill_datatable(filter_district, filter_outlet);
}
else
{
alert('Select Both filter option');
}
});
$('#reset').click(function(){
$('#filter_district').val('');
$('#filter_outlet').val('');
$('#store_data').DataTable().destroy();
fill_datatable();
});
});
</script>
Now I'm Displaying the latitude and the longitude value from the database in the table.
This is how it looks links in the ui
i want to have an extra column with a link saying find location next to every stores which will redirect the users with the exact store latitude and the longitude value to the google map .
I hope my problem is understandable, please help me how can i do it, any tips ?
Google Maps is in a projected coordinate system that is based on the wgs84 datum. (EPSG 3857). For this reason, you can use directly the latitude and longitude.
To identify a business, Google Maps use PlaceID. To show the name's business, you need to know each PlaceID. I think you need to add this extra column for your database. (varchar type)
To search a PlaceID in Google Maps.
https://developers.google.com/maps/documentation/javascript/examples/places-placeid-finder
This is an example url in Google Maps with longitude,latitude and placeID (reference)
https://www.google.com/maps/search/?api=1&query=47.5951518,-122.3316393&query_place_id=ChIJKxjxuaNqkFQR3CK6O1HNNqY
To generate this url in your project. I think the cleanest option are put it on the model
class StoreFC {
...
public function getGmapUrlAttribute() {
return "https://www.google.com/maps/search/?api=1&query=".$this->latitude.",".$this->longitude".&query_place_id=".$this->place_id;
}
}
To use in StoreFCController:
..
function index(Request $request)
{
if(request()->ajax())
{
if(!empty($request->filter_district))
{
$data = StoreFC::select('id','loc_type', 'loc_group', 'loc_code', 'location', 'location_2', 'status', 'phone', 'address', 'gmap_url')
->where('location', $request->filter_district)
->where('loc_type', $request->filter_outlet)
->get();
}
...
I hope this will be helpful to you. Cheers!

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;
}
}
});

yajra/laravel-datatables, Reply Slow

Summary of problem or feature request
The reply o load datatable is very slow, betwen 3-5seg
How can I optimize the data load?
when I did not use server inside it was much faster..
first of all, Thanks
Code snippet of problem
Controller
public function list_user(){
$users = User::all();
$users->each(function ($users)
{
$users->role;
});
return datatables()->collection($users)->toJson();
}
Js
function activar_tabla_users() {
$('#DataTableUser').DataTable({
"processing" : true,
"serverSide" : true,
"searchDelay" : 500,
"responsive": {
orthogonal: 'responsive'
},
"language": {
"url": '{!! asset('/plugins/datatables.net/latino.json') !!}'
} ,
"lengthMenu": [5,10, 25, 50, 75 ],
"ajax":'{!! url('admin/list_user') !!}',
columns: [
{data: 'id' },
{data: 'username'},
{data: 'name',
render: function (data, type, row, meta) {
return row.name + ' ' + row.lastname;
}
},
{data: 'email'},
{data: 'role.name',
render: function(data, type, row, meta) {
var html = ''
if ( row.role.name == 'Administrador' )
{
html = '<span class="label label-danger" > <label style="width:80px;"> '+row.role.name+' </label></span>';
}else {
html = '<span class="label label-primary" > <label style="width:80px;"> '+row.role.name+' </label></span>';
}
return html;
}
}
}],
});
}
activar_tabla_users();
You are using server side to get table data. Don't call all() as it will get all.
Replace:
$users = User::all();
With:
$users = User::query();
This only renders the required data in data-table page.
And, don't use loop to get role. Use eager loading using with();
$users = User::query()->with('role');
$users = User::all();
$users->each(function ($users)
{
$users->role;
});
with this the following?
$users = User::with('role');
Datatable adds pagination options automatically. if you use all() it calls all the data from the table.
Another thing is did you checked that it takes 2/3sec to get data from the server or does it takes this time to format the data in the view?
replace
$users = User::all();
$users->each(function ($users)
{
$users->role;
});
with this:
$users = User::with('role')->get();
This will use one db request instead of over 1k requests (you were making a call for each user to get their role). If you display all 1300 users at once, only request the "page" you need with laravels built in pagination, https://laravel.com/docs/5.6/pagination#paginating-eloquent-results

Return view json response

I try to pass a return json to my view but I get an error who say that I didn't past all the variables objects to the view, the problem if I pass all the variables in my table I get all my web page in the table wish is no sense..
someone know how I could do?
here my controller:
public function searchEquipes(Request $request)
{
if ($request->has('poule_id')) {
$equipes = EquipePoule::where('poule_id' , $request->poule_id)->get();
return response()->json([
'table' => view("competitions/show", compact('equipes'))->render(),
]);
}else {
//nothing
}
}
here my view:
#foreach($equipes as $equipe)
<tr>
<td>{{$equipe->equipe->structure->nom_structure}}</td>
<td>{{$equipe->equipe->lb_equipe}}</td>
<td>{!! Form::text('nb_bonus') !!}</td>
</tr>
#endforeach
here my script:
<script>
$('#poule').change(function () {
$.ajax({
type: 'GET',
url : 'search/equipes',
dataType: "json",
data : {
poule_id : document.getElementById('poule').value
},
success:function(data){
$('#equipes').html(data.table);
}
});
});
</script>
i guess you are not returning the json response the right way try using
return response()->json([$equipes]);
success:function(data){
//loop $equipes here
}

datatable pagination in laravel

I am using laravel 5.0
I am also using datatable jquery plugin to display grid.
Controller mehtod
public function index() {
$jobs = \App\Job::orderBy('created_at', 'DESC')->limit(1000)->get();
return View::make('jobs.index', ['jobs' => $jobs]);
}
The issue:
Right now I hard-coded the ->limit(1000) to 1000 jobs in datatable grid to display
it but i have more then 1000 records to display.
What I want?
I want to display 500 records with grid and then 500 records.
I am not sure if there is any call back data-table plugin function available?
I need a dynamic way to load next 500
NOTE:
I am not willing to us this solution of scrolling
https://datatables.net/extensions/scroller/examples/initialisation/server-side_processing.html
You can user ajax data source:
please visit : https://datatables.net/examples/ajax/objects.html
Example PHP Script:
// function will process the ajax request
public function getMembers(Request $request) {
$draw = $request->get('draw');
$start = $request->get('start');
$length = $request->get('length');
$search = (isset($filter['value']))? $filter['value'] : false;
$total_members = 1000; // get your total no of data;
$members = $this->methodToGetMembers($start, $length); //supply start and length of the table data
$data = array(
'draw' => $draw,
'recordsTotal' => $total_members,
'recordsFiltered' => $total_members,
'data' => $members,
);
echo json_encode($data);
}
Example JavaScript :
$('#all-member-table').DataTable( {
"processing": true,
"serverSide": true,
"ajax": {
url: base_url+"ajax/members"
},
"columns": [
{ data: '1' },
{ data: '2' },
{ data: '3' },
{ data: '4' },
{ data: '5' },
]
} );
Example HTML:
<table id="all-member-table">
<thead>
<tr>
<th>Column1</th>
<th>Column2</th>
<th>Column3</th>
<th>Column4</th>
<th>Column5</th>
</tr>
</thead>
</table>
I think above answer should be extended with search feature.
Update the answer;
$filter = $request->get('search');
$search = (isset($filter['value']))? $filter['value'] : false;
where('somecolumnonyourdb','like', '%'.$search.'%')
This works for me
You can use standard pagination:
$jobs = \App\Job::latest()->paginate(500);
Or create it manually.

Resources