i have problem with yajra datatables to make row group in server side. I want row group show all employee in companies.name. and my current code like this:
public function index(DataTablesBuilderService $builder)
{
$columns = [
'name' => [
'title' => "company",
'name' => 'companies.name'
];
$dataTables = $builder
->setUrl(route('api.employee_details.data_tables', request()->all()))
->withIndex()
->setColumns($columns);
return view('employee_details.index')->with([
'dataTables' => $dataTables,
]);
}
and in blade i just call datatable like this
{!! $dataTables->table(['class' => 'table table-bordered','style' => 'width:100%', 'cellspacing' => '0']) !!}
and the script like this
{!! $dataTables->scripts() !!}
If i following the tutorial on https://datatables.yajrabox.com/eloquent/master, its possible to make row group but i dont know how to implement in server side. But is so different with my code in blade. Tutorial call datatable like this.
var template = Handlebars.compile($("#details-template").html());
var table = $('#users-table').DataTable({
processing: true,
serverSide: true,
ajax: 'https://datatables.yajrabox.com/eloquent/master-data',
columns: [
{
"className": 'details-control',
"orderable": false,
"searchable": false,
"data": null,
"defaultContent": ''
},
{data: 'id', name: 'id'},
{data: 'name', name: 'name'},
{data: 'email', name: 'email'},
{data: 'created_at', name: 'created_at'},
{data: 'updated_at', name: 'updated_at'}
],
order: [[1, 'asc']]
});
// Add event listener for opening and closing details
$('#users-table tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row(tr);
var tableId = 'posts-' + row.data().id;
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
} else {
// Open this row
row.child(template(row.data())).show();
initTable(tableId, row.data());
tr.addClass('shown');
tr.next().find('td').addClass('no-padding bg-gray');
}
});
function initTable(tableId, data) {
$('#' + tableId).DataTable({
processing: true,
serverSide: true,
ajax: data.details_url,
columns: [
{ data: 'id', name: 'id' },
{ data: 'title', name: 'title' }
]
})
}
and the result like this and i expected like this to but in datatables server side
Thank you if you can help to help me and explain how to solve the problem code
Injecting this in your DataTable options may help you (I've tried and it's working in my case)
$(selector).DataTable({
startRender: function (rows, group) {
var grpName = rows.data().pluck('company')
.reduce(function (a, b) {
return (b === null ? '' : b);
}, '');
return $('<tr/>')
.append('<td colspan="' + columns.length + '" class="text-left"><span class="ml-10px">' + grpName + '</span></td>');
},
endRender: null,
dataSrc: 'company'
})
Related
I'm currently using datatabels 7.0 and Laravel 5.4
data in my grid is showing correctly but when I want to search on nested relationship column I got below error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'course_semester.semester.name' in 'where clause' (SQL: select count(*) as aggregate from (select '1' as `row_count` from `videos` where LOWER(`videos`.`id`) LIKE %%te%% and LOWER(`videos`.`name`) LIKE %%te%% and LOWER(`course_semester`.`semester`.`name`) LIKE %%te%%) count_row_table)
Here is my code
Controller
$videos = Video::with(['course_semester' => function ($query) {
return $query->with('course', 'semester');
}])->select('videos.*');
return Datatables::of($videos)
->addColumn('check', '<input type="checkbox" name="selected-videos" value="{{$id}}">')
->escapeColumns([])
->make(true);
Javascript
columns: [
{ data: 'check' , name: 'check',orderable: false, searchable: false },
{ data: 'id', name: 'videos.id' },
{ data: 'name', name: 'videos.name' },
{ data: 'course_semester.semester.name', name: 'course_semester.semester.name'},
{ data: 'course_semester.course.name', name: 'course_semester.course.name'},
{ data: 'status', name: 'videos.status' },
{ data: 'comment', name: 'videos.comment' },
{ data: 'video_date', name: 'videos.video_date' },
]
Can anyone help me and notice my problem?
Thanks in advance.
Because of using select() here, you do not load the relationship. Also, use dot syntax for nested eager loading:
$videos = Video::with(['course_semester', 'course_semester.course'])
1- dataTable function
public function dataTable($query)
{
return datatables()
->eloquent($query)
->addColumn('BulkSelection', function ($category)
{
->addColumn('company', function ($category)
{
return $category->company ? $category->company->name : 'No Company';
})
->rawColumns(['action', 'company', 'createdAt','BulkSelection']);
}
2- query function
public function query(Category $model)
{
return $model->with('company:id,name')->select('categories.*')->newQuery();
}
3- getColumns function
$getCols = [
'id',
'name',
'company'=> [
'data'=>'company',
'name'=>'company.name'
],
'createdAt' => [
'name'=>'created_at',
'searchable' => false
],
'action' => [
'exportable' => false,
'searchable'=>false,
'orderable' => false
]
];
return $getCols;
If you just need to load the data from relation tables, use the below code
$videos = Video::with('course_semester','course', 'semester')->select('videos.*');
return Datatables::eloquent($videos)
->addColumn('check', function(Video $v){
return '<input type="checkbox" name="selected-videos" value="{{$v->id}}">'
})
->rawColumns(['check'])
->make(true);
And in script, you can call relation values as ,
{data: 'course_semester.id'},
{data: 'course.name'},
{data: 'semester.name'},
$getCols = [
'title',
'Images' => [
'name'=>'images_count',
'data'=>'images_count',
'searchable'=>false
],
'price' => ['name'=>'start_price', 'data'=>'start_price'],
'reserve_price',
'Category' => [
'data'=>'show_category',
'name'=>'categories.name',
'searchable'=>false
],
'created_by' => [
'name'=>'user.name',
],
'createdAt' => [
'name'=>'created_at',
'searchable' => false
],
'action' => [
'exportable' => false,
'searchable'=>false,
'orderable' => false
]
I am creating a datatable using Laravel's Yajra plugin. I am using the query builder form.(Like this Click here)
I wanna add buttons CSV,PDF to the datatable.
I know as per the documentation it can be done Like this
The problem is I have already done using query builder. Now I cannot change my code.
Kindly help me.
My jquery code is as follows:
<script type="text/javascript">
$(document).ready(function(){
$('body').addClass('sidebar-collapse');
var cat = "{{$cat}}";
$('#unreconcil_datatable').DataTable({
processing: true,
serverSide: true,
ajax: '{!! route('get_datatable',array('cat'=>$cat)) !!}',
columns: [
{ data: 'unrelines_uniq_num', name: 'unrelines_uniq_num' },
{ data: 'unrelines_bank_accno', name: 'unrelines_bank_accno' },
{ data:'unrelines_rficreated',name:'unrelines_rficreated'},
{ data: 'unrelines_roicreated', name: 'unrelines_roicreated' },
{ data: 'unrelines_bank_name', name: 'unrelines_bank_name' },
{ data: 'unrelines_line_number', name: 'unrelines_line_number' },
{ data: 'unrelines_state_date', name: 'unrelines_state_date' },
{ data: 'unrelines_trans_date', name: 'unrelines_trans_date' },
{ data: 'unrelines_trans_amount', name: 'unrelines_trans_amount' },
{ data: 'unrelines_unrec_amt', name: 'unrelines_unrec_amt' },
{ data: 'unrelines_desc', name: 'unrelines_desc' },
{ data: 'unrelines_variance', name: 'unrelines_variance' },
{ data: 'unrelines_cstatus', name: 'unrelines_cstatus' },
{ data: 'unrelines_assigned', name: 'unrelines_assigned' },
{ data: 'unrelines_created_date', name: 'unrelines_created_date' },
{data: 'tat', name: 'tat', orderable: false, searchable: false},
{data: 'action', name: 'action', orderable: false, searchable: false}
]
});
});
</script>
My controller method is as follows:
public function getdatatable($cat){
$list = AvailableStatementLines::select([DB::raw(" '$cat' AS cat"),'unrelines_id','unrelines_uniq_num','unrelines_bank_accno','unrelines_rficreated','unrelines_roicreated','unrelines_bank_name','unrelines_line_number','unrelines_state_date','unrelines_trans_date','unrelines_trans_amount','unrelines_unrec_amt','unrelines_desc','unrelines_variance','unrelines_cstatus','unrelines_assigned','unrelines_created_date','unrelines_trans_type','unrelines_currency','unrelines_created_by_name','unrelines_ustatus',DB::raw("IF(unrelines_cstatus='closed', '',
ROUND(ABS(TIMESTAMPDIFF(MINUTE, date(unrelines_lastupdate), curdate()))/1440 - ABS(DATEDIFF(ADDDATE(curdate(), INTERVAL 1 -DAYOFWEEK(curdate()) DAY), ADDDATE(date(unrelines_lastupdate), INTERVAL 1 -DAYOFWEEK(date(unrelines_lastupdate)) DAY))) / 7 * 2 - (DAYOFWEEK(IF(date(unrelines_lastupdate) < curdate(), date(unrelines_lastupdate), curdate())) = 1) - (DAYOFWEEK(IF(date(unrelines_lastupdate) > curdate(), date(unrelines_lastupdate), curdate())) = 7),0)
) AS tat")])->where('unrelines_ucountry',Session::get('country'))->where('unrelines_display',1);
switch($cat){
case 'rfi':
$list1 = $list->where('unrelines_cstatus','Assigned');
break;
case 'roi':
$list1 = $list->where('unrelines_cstatus','Solution Provided');
break;
case 'closed':
$list1 = $list->where('unrelines_cstatus','Closed');
break;
default:
$list1 = $list->whereNotIn('unrelines_cstatus',['Closed','Assigned','Solution Provided']);
break;
}
return Datatables::of($list1)
->addColumn('unrelines_uniq_num',function($list1){
return "<input type='checkbox' class='uniqnums' name='uniquenum[]' value='".$list1->unrelines_id."'>".$list1->unrelines_uniq_num;
})
->addColumn('action',function($list1){
return "<button type='button' class='btn btn-xs btn-info viewLine' category=".$list1->cat." unrelines=".$list1->unrelines_id.">View</button>";
})
->setRowClass(function ($list1) {
return $list1->tat > 7 ? 'orange' : ($list1->tat > 5 ? 'red' : ' ');
})
->make(true);
}
You should apply this method in your controller.
public function html()
{
return $this->builder()
->columns([
'id',
'name',
'email',
'created_at',
'updated_at',
])
->parameters([
'dom' => 'Bfrtip',
'buttons' => ['csv', 'excel', 'pdf', 'print', 'reset', 'reload'],
]);
}
This is the bill_info table, for which i need to serialized row no like 1 2 . . . . . . . . . . . . .n
There is data list returned, how I can get serial_no custom field in datatable list view.
$data = BillInfo::get(['bill_info.*']);
return Datatables::of($data)
->removeColumn('id')
->make(true);
If you are using yajra laravel datatables
Just add ->addIndexColumn()
return DataTables::of($data)
->addIndexColumn()
->make(true);
In your javascript, you can set the first row as a serial number like this
columns: [
{ data: 'DT_RowIndex', name: 'DT_RowIndex', orderable: false, searchable: false },
{ data: 'name', name: 'name' },
{ data: 'action', name: 'action' }
]
use DT_Row_Index instead of DT_RowIndex for older yajra datatable version
When using Yajra Laravel datatables
return DataTables::of($result)
->addIndexColumn()
->make(true);
"columns": [
{
"data": 'DT_RowIndex',
orderable: false,
searchable: false
},
]
Set the variable rownum at the beginning of your query. Then set the increment process in your query.
DB::statement(DB::raw('set #rownum=0'));
$data = BillInfo::get(['bill_info.*',
DB::raw('#rownum := #rownum + 1 AS rownum')]);
return Datatables::of($data)
->removeColumn('id')
->make(true);
Here you can get rownum as serial no of the given records [1 . . . 8].
In Laravel Yajra Datatables v9.x as Service Implementation, I add this in getColumns function and works well in sorting, searching, and page changing.
'id' => ['title' => 'N.', 'orderable' => false, 'searchable' => false, 'render' => function() {
return 'function(data,type,fullData,meta){return meta.settings._iDisplayStart+meta.row+1;}';
}],
You can see my code :
<table id="datatable" class="table table-bordered table-striped">
<thead>
<tr>
<th>Sl No</th>
<th>Invoice No</th>
<th>Customer</th>
<th>Total Price</th>
<th>Paid</th>
<th>Due</th>
<th>Discount</th>
<th>Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
And the script part:
<script type="text/javascript">
$(function() {
var i = 1;
var table = $('#datatable').DataTable({
processing: true,
serverSide: true,
ajax: "{{ route('collections') }}",
columns: [{
"render": function() {
return i++;
}
},
{
data: 'issue_no',
name: 'issue_no'
},
{
data: 'customer_name',
name: 'customer_name'
},
{
data: 'total_order_price',
name: 'total_order_price'
},
{
data: 'paid_amount',
name: 'paid_amount'
},
{
data: 'due_amount',
name: 'due_amount'
},
{
data: 'discount_amount',
name: 'discount_amount'
},
{
data: 'action',
name: 'action',
orderable: false,
searchable: false
}
],
createdRow: function ( row, data, index ) {
if (data['due_amount'] > 0) {
$('td', row).eq(4).css('background-color', '#f4511e','color','#ffffff');
$('td', row).eq(4).css('color','#ffffff');
} else {
}
$('td', row).eq(3).addClass('text-right');
$('td', row).eq(4).addClass('text-right');
$('td', row).eq(5).addClass('text-right');
$('td', row).eq(6).addClass('text-right');
}
});
});
</script>
In the rendering part, you can add the auto-increment field
{
"render": function() {
return i++;
}
},
simple using render function script on yajra datatable, this is my code:
protected function getColumns()
{
return [
Column::make('row_number')
->title('#')
->render('meta.row + meta.settings._iDisplayStart + 1;')
->width(50)
->orderable(false),
];
}
Here is my existing JS code:
var CategoriesTablewithFilter = function(){
var table = $('#catDatatable');
var url = $('#url').val();
var tableObj = table.DataTable( {
"serverSide": true,
"responsive": true,
"aoColumnDefs": [
{ "bSearchable": true, "aTargets": [ 1 ] },
],
ajax:
{
url: url,
dataSrc: 'data',
},
columns: [
{ data: 'id'},
{ data: 'name'},
{ data: 'status'},
],
} );
}
Status is a Boolean field which returns 1 or 0.
Is there anyway I can change 1, 0 to Strings - Active/InActive
You should use render function for column:
var CategoriesTablewithFilter = function () {
var table = $('#catDatatable');
var url = $('#url').val();
var tableObj = table.DataTable({
"serverSide": true,
"responsive": true,
"aoColumnDefs": [
{"bSearchable": true, "aTargets": [1]},
],
ajax:
{
url: url,
dataSrc: 'data',
},
columns: [
{data: 'id'},
{data: 'name'},
{data: 'status', render: function (data, type, row, meta) {
return data == 1 ? 'Active' : 'InActive';
}}
],
});
}
Try debugging you ajax response using console.log(data) output to fetch status's value and use render function to display render the final output.
columns: [
{ data: 'id'},
{ data: 'name'},
{
data: 'status',
render: function (data, type, full, meta) {
return full.status == true ? 'Active' : 'Inactive';
}
}
]
Or you could use
columns: [
{ data: 'id'},
{ data: 'name'},
{
data: 'status',
render: function (data, type, full, meta) {
return data === '1' ? 'Active' : 'Inactive';
}
}
]
I have a customers table with each record linking to a customer contact:
http://localhost/untdchem/public/home/customers/contacts/1809
When I click on the above link, I want to display all the contacts for customer 1809 only in a datatable. I am trying to pass the customer ID somehow so I can filter for that customer only. I can fill the table with all the contacts but i want to just load for that customer.
Routes:
//Customer Contacts
Route::get('home/customers/contacts', ['as' => 'customers.contacts', 'uses' => 'CustomerContactsController#index']);
Route::get('home/customers/contacts/data', ['as' => 'customers.contacts.data', 'uses' => 'CustomerContactsController#anyData']);
In my controller:
public function index()
{
// GET request to index
return view('pages.customer_contacts.index');
}
public function anyData()
{
$contacts = customer_contact::select(['CustContactFName','CustContactLName','CustContactCountryCode','CustContactExtension','CustContactPhone','CustContactEmail','CustContactType']);
return Datatables::of($contacts)->make(true);
}
In my view:
<script>
$(function() {
$('#customer-contacts-table').DataTable({
processing: true,
serverSide: true,
ajax: '{!! route('customers.contacts.data') !!}',
columns: [
{ data: 'CustContactFName', name: 'CustContactFName'},
{ data: 'CustContactLName', name: 'CustContactLName'},
{ data: 'CustContactCountryCode', name: 'CustContactCountryCode'},
{ data: 'CustContactExtension', name: 'CustContactExtension'},
{ data: 'CustContactPhone', name: 'CustContactPhone'},
{ data: 'CustContactEmail', name: 'CustContactEmail'},
{ data: 'CustContactType', name: 'CustContactType'}
//{ data: 'action', name: 'action', orderable: false, searchable: false}
],
order: [[0, "desc" ]]
});
});
</script>
Routes
Route::get('home/customers/contacts/{id}', ['as' => 'customers.contacts', 'uses' => 'CustomerContactsController#index']);
Route::get('home/customers/contacts/data/{id}', ['as' => 'customers.contacts.data', 'uses' => 'CustomerContactsController#anyData']);
Controller
I am assuming there is CustId field that identifies which customer the contact record is assigned to. If your structure is different, adjust accordingly.
public function index($id) {
// GET request to index
return view('pages.customer_contacts.index', compact('id'));
}
public function anyData($id){
$contacts = customer_contact::select([
'CustContactFName',
'CustContactLName',
'CustContactCountryCode',
'CustContactExtension',
'CustContactPhone',
'CustContactEmail',
'CustContactType'
])
->where('CustId', '=', $id);
return Datatables::of($contacts)->make(true);
}
JavaScript
Update the line with ajax option:
ajax: '{!! route('customers.contacts.data', ['id' => $id]) !!}',
The correct solution below:
public function index($CustID = null, Request $request)
{
if ($request->ajax()) {
$contacts = customer_contact::select(['CustContactFName','CustContactLName','CustContactCountryCode','CustContactExtension','CustContactPhone','CustContactEmail','CustContactType']);
if ($CustID) {
$contacts->where('CustID', $CustID);
}
//dd($contacts);
return Datatables::of($contacts)
->addColumn('action', function ($contacts) {
$links="";
$links.='Edit | ';
$links.='<a class="delete" href="'.url('home/customers/contacts/delete', [$contacts->CustID]).'">Delete</a> | ';
return $links;
})->make(true);
}
return view('pages.customer_contacts.index', compact('CustID'));
}
<script>
$(function() {
$('#customer-contacts-table').DataTable({
processing: true,
serverSide: true,
ajax: '{!! route('customers.contacts', $CustID) !!}',
columns: [
{ data: 'CustContactFName', name: 'CustContactFName'},
{ data: 'CustContactLName', name: 'CustContactLName'},
{ data: 'CustContactCountryCode', name: 'CustContactCountryCode'},
{ data: 'CustContactExtension', name: 'CustContactExtension'},
{ data: 'CustContactPhone', name: 'CustContactPhone'},
{ data: 'CustContactEmail', name: 'CustContactEmail'},
{ data: 'CustContactType', name: 'CustContactType'},
{ data: 'action', name: 'action', orderable: false, searchable: false}
],
order: [[0, "desc" ]]
});
});
</script>