First, great job for this amazing package.
I have a small problem:
I added a new custom column in your demo file: .../eloquent/add-edit-remove-column, I want to search/filter for that column, but I get an error in browser when I input everything.
Is there a solution to search/filter in a custom column and after that to add a search input text for every column in table, including for custom_column?
Error in FireBug console:
<span class="exception_message">SQLSTATE[42S22]: Column not found: 1054 Champ
'new_column' inconnu dans where clause (SQL: select count(*) as aggregate from (select '
;1' as row_count from `users` where (LOWER(`id`) LIKE %b% or LOWER(`name`) LIKE %b% or LOWER(`email
`) LIKE %b% or LOWER(`created_at`) LIKE %b% or LOWER(`updated_at`) LIKE %b% or LOWER(`new_column`) LIKE
%b%)) count_row_table)</span>
Code from Controller:
public function getAddEditRemoveColumnData()
{
$users = User::select(['id', 'name', 'email', 'password', 'created_at', 'updated_at']);
return Datatables::of($users)
->addColumn('new_column' , 'ABC')
->make(true)
}
Code from Javascript:
$('#users-table').DataTable({
processing: true,
serverSide: true,
ajax: '{{ url("eloquent/add-edit-remove-column-data") }}',
columns: [
{data: 'id', name: 'id'},
{data: 'name', name: 'name'},
{data: 'email', name: 'email'},
{data: 'created_at', name: 'created_at'},
{data: 'updated_at', name: 'updated_at'},
{data: 'new_column', custom: 'new_column', orderable: true, searchable: true}
]
});
@marioene, you cannot search on addColumn
if the data is not from the database. A workaround for this is to add the column on your select statement like below. No need to use addColumn
.
$users = User::select([
'id', 'name', 'email', 'password', 'created_at', 'updated_at',
DB::raw("'ABC' as new_column")
]);
Note: You may have to write a custom
filterColumn
for it to work. Just make sure the sql generated is working and it should work with the package too.
Closing due to inactivity and suggested workaround above should fix the issue. Thanks!
@yajra I followed your suggestion to first add a calculated column using 'select' (in Controller)
$staffData = Staff::select('id', 'staff_id', \DB::raw('concat(first_name, " ", middle_name, " ", last_name) as full_name'), 'department_name', 'status');
Then I added a custom filter (in Controller)
$dt = Datatables::of($staffData);
return $dt->filterColumn('full_name', function($query, $keyword) {
$query->whereRaw("CONCAT(first_name, ' ', middle_name, ' ', last_name) like ?", ["%{$keyword}%"]);
})->make(true);
When I first load the the page, data table is rendered properly by when I do search using the global search input text box, an error is being thrown
Ajax error. http://datatables.net/tn/7
Can you please let me know where I might be making mistake.
@AshishGupta001 try inspecting the ajax request using chrome dev tools or firebug. It will give you a hint on what's causing the issue. Most probably, an sql exception issue.
@yajara Thanks for your quick response.
While implementing the global search for a 'calculated' column (in my case 'full_name') I took reference to
1) Issue 168 : https://github.com/yajra/laravel-datatables/issues/168
2) Example: https://datatables.yajrabox.com/eloquent/post-column-search
Before I added the custom 'filterColumn()' for my datatable, I was getting SQL exception complaining for missing column 'full_name' in the table. Then I added below code to add a custom filter for 'calculated' column (in my case 'full_name') as below
$dt->filterColumn('full_name', function($query, $keyword) {
$query->whereRaw("CONCAT(staff.first_name, ' ', staff.middle_name, ' ', staff.last_name) like ?", ["%{$keyword}%"]);
});
return $dt->make(true);
Now I get following error in the log
mb_strtolower() expects parameter 1 to be string, object given
in file ......./vendor/laravel/framework/src/Illuminate/Support/Str.php#162
Appreciate if you can help debug this issue.
@AshishGupta001 what version are you using? Your code looks fine to me.
@yajra Thanks for confirming. Versions are as below
PHP - 5.5.38-3
Laravel - 5.0.34
Datatables - yajra/laravel-datatables-oracle: ^6.3 (as in composer.json)
It seems in 'getOrMethod' in Helper class, exception is being thrown as it is trying to convert to lower a "clouser" passed as a input param.
public static function getOrMethod($method) {
if (! Str::contains(Str::lower($method), 'or')) {
return 'or' . ucfirst($method);
}
return $method;
}
'$method' is a clouser as passed function($query, $keyword)
, as below
Closure {#864
reflection: """
Closure [ <user> public method App\Http\Controllers\{closure} ] {\n
@@ /var/www/html/XYZ/app/Http/Controllers/StaffHistoryController.php 310 - 313\n
\n
- Parameters [2] {\n
Parameter #0 [ <required> $query ]\n
Parameter #1 [ <required> $keyword ]\n
}\n
}\n
"""
}
Though I could not figure out the issue I faced, I was able to find out the way around this specific use case. Thanks for the hints available here.
View: Have the following in the View within the script tag
{ data: 'full_name', name: 'full_name', searchable: false },
{ data: 'first_name', name: 'first_name', searchable: true, visible: false },
{ data: 'middle_name', name: 'middle_name', searchable: true, visible: false },
{ data: 'last_name', name: 'last_name', searchable: true, visible: false }
Controller: Fetch first_name etc in the SQL query along with rest of the column values.
@AshishGupta001 glad you figured that out. That is what I used to do too since Laravel 4.2 version. 👍
@AshishGupta001 Good solution!
@yajra Can we search an added column using the addColumn which it's data coming from the database but we are not adding this column in the JS ?
Or we should add it to the JS and make it invisible but searchable ?
Some ways I can think of:
{data: 'added_column', name: 'actual_column_name'}
Thanks for your quick response @yajra
I was already trying the second solution but I noticed this added column is not considered in the query.
Any thoughts ?
Make sure you did not add searchable: false
on that column.
This is how I added the column ->addColumn('company_name', function($deal) {
return $deal->company_name;
})
And the global search query as $dataTable->filterColumn('company_name', 'where', "like", ["%$keyword%"]);
Can we pass the searchable: false
in the backend?
searchable: false
is on the client-side js.
BTW, what version are you using?
Ah ok. So we still need to use the first way you mentioned, with this way.
I'm using v6.17.0
I am having the same issue as @AshishGupta001 unfortunately the client-side trick does not cut it as the column is not sortable.
I have explored the filterColumn alternative but could not get it to work too.
using "yajra/laravel-datatables-oracle": "~9.0"
controller method:
public function getAccounts(Request $request)
{
if ($request->ajax()) {
$accounts = Account::with('current_marketer')->select([
'*',
DB::raw("CONCAT(accounts.lastname,' ',accounts.firstname) as fullname"),
]);
return Datatables::of(Account::query()->with('current_marketer'))
->addColumn('marketer', function(Account $account){
return $account->current_marketer->name;
})
->addColumn('fullname', function($account){
return '<a href="'.route('account.clients.show', $account->account_number).'" class="hover:underline" target="_blank">'. $account->fullname.'</a>';
})
->filterColumn('fullname', function($query, $keyword) {
$sql = "CONCAT(accounts.lastname,' ',accounts.firstname) like ?";
$$query->whereRaw($sql, ["%{$keyword}%"]);
})
->rawColumns(['fullname'])
->editColumn('created_on', function(Account $account) {
return Carbon::parse($account->created_on)->format('jS F, Y');
})
->toJson();
}
return view('datatables.accounts.index');
}
Blade js:
$('#accounts-table').DataTable({
"processing": true,
"serverSide": true,
"ajax": '{{ route('accounts.get') }}',
"columns": [
{ data: "id" },
{ data: "account_number" },
{ data: 'fullname'},
{ data: "marketer" },
{ data: "created_on" },
]
});
Exception: when searching or sorting is attempted:
as it turns out the issue with that exception was my fault; I had a double '$$' sign within my filterColumn method.
That didn't fix my sorting problem though. I still need to know :
@seewhy17 you can use orderColumn for complex sorting. However in your case, ordering by fullname
would already work out of the box afaik.
@seewhy17 you can use orderColumn for complex sorting. However in your case, ordering by
fullname
would already work out of the box afaik.
Well it didn't, I guess the filterColumn method conflicts with an Assessor on the Model which basically does the same thing...I really do not know.
For know I got it to kind of work with by adding a name: lastname
to the js, so it filters by lastname and filterColumn method is redundant
Most helpful comment
@marioene, you cannot search on
addColumn
if the data is not from the database. A workaround for this is to add the column on your select statement like below. No need to useaddColumn
.