Laravel-datatables: 如何在由 addColumn 生成的列中搜索?

创建于 2015-08-03  ·  22评论  ·  资料来源: yajra/laravel-datatables

首先,这个惊人的包裹做得很好。

我有一个小问题:

我在您的演示文件中添加了一个新的自定义列:.../eloquent/add-edit-remove-column,我想搜索/过滤该列,但是当我输入所有内容时,在浏览器中出现错误。

是否有解决方案可以在自定义列中搜索/过滤,然后为表中的每一列添加搜索输入文本,包括 custom_column?

FireBug 控制台中的错误:

  <span class="exception_message">SQLSTATE[42S22]: Column not found: 1054 Champ
 &#039;new_column&#039; inconnu dans where clause (SQL: select count(*) as aggregate from (select &#039
;1&#039; 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>

来自控制器的代码:

    public function getAddEditRemoveColumnData()
    {
        $users = User::select(['id', 'name', 'email', 'password', 'created_at', 'updated_at']);

        return Datatables::of($users)
                                 ->addColumn('new_column' , 'ABC')
                                  ->make(true)
    }

来自 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 ,如果数据不是来自数据库,则无法搜索addColumn 。 一种解决方法是在您的选择语句中添加列,如下所示。 无需使用addColumn

$users = User::select([
'id', 'name', 'email', 'password', 'created_at', 'updated_at',
DB::raw("'ABC' as new_column")
]);

注意:您可能必须编写自定义filterColumn才能使其工作。 只要确保生成的 sql 正常工作,它也应该与包一起工作。

所有22条评论

@marioene ,如果数据不是来自数据库,则无法搜索addColumn 。 一种解决方法是在您的选择语句中添加列,如下所示。 无需使用addColumn

$users = User::select([
'id', 'name', 'email', 'password', 'created_at', 'updated_at',
DB::raw("'ABC' as new_column")
]);

注意:您可能必须编写自定义filterColumn才能使其工作。 只要确保生成的 sql 正常工作,它也应该与包一起工作。

由于不活动而关闭和上面建议的解决方法应该可以解决问题。 谢谢!

@yajra我按照您的建议首先使用“选择”(在控制器中)添加计算列

$staffData = Staff::select('id', 'staff_id', \DB::raw('concat(first_name, " ", middle_name, " ", last_name) as full_name'), 'department_name', 'status');

然后我添加了一个自定义过滤器(在控制器中)

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

当我第一次加载页面时,当我使用全局搜索输入文本框进行搜索时,数据表正确呈现,抛出错误

Ajax error. http://datatables.net/tn/7

你能告诉我我可能在哪里出错吗?

@AshishGupta001尝试使用 chrome 开发工具或 firebug 检查 ajax 请求。 它将提示您是什么导致了问题。 很可能是一个 sql 异常问题。

@yajara感谢您的快速回复。
在实现对“计算”列(在我的情况下为“full_name”)的全局搜索时,我参考了
1) 第 168 期:https://github.com/yajra/laravel-datatables/issues/168
2)示例: https :

在为数据表添加自定义“filterColumn()”之前,我收到 SQL 异常,抱怨表中缺少“full_name”列。 然后我添加了下面的代码来为“计算”列(在我的例子中是“full_name”)添加一个自定义过滤器,如下所示

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

现在我在日志中收到以下错误

mb_strtolower() expects parameter 1 to be string, object given文件......./vendor/laravel/framework/src/Illuminate/Support/Str.php#162

感谢您是否可以帮助调试此问题。

@AshishGupta001您使用的是什么版本? 你的代码对我来说很好。

@yajra感谢您的确认。 版本如下

PHP - 5.5.38-3
Laravel - 5.0.34
数据表- yajra/laravel-datatables-oracle:^6.3(如 composer.json)

似乎在 Helper 类的 'getOrMethod' 中,抛出异常,因为它试图转换为降低作为输入参数传递的“clouser”。

public static function getOrMethod($method) {
   if (! Str::contains(Str::lower($method), 'or')) {
      return 'or' . ucfirst($method);
   }
      return $method;
}

'$method' 是通过function($query, $keyword)的clouser,如下

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
    """
}

虽然我无法弄清楚我面临的问题,但我能够找到解决这个特定用例的方法。 感谢此处提供的提示。

视图:脚本标签内的视图中具有以下内容

{ 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 }

控制器:在 SQL 查询中获取 first_name 等以及其余的列值。

@AshishGupta001很高兴你发现了这一点。 从 Laravel 4.2 版本开始,我也是这样做的。 👍

@AshishGupta001很好的解决方案!

@yajra我们可以使用 addColumn 搜索添加的列,它是来自数据库的数据,但我们没有在 JS 中添加此列吗?

或者我们应该将它添加到 JS 并使其不可见但可搜索?

我能想到的一些方法:

  1. 把它添加到js中,并按照你说的让它不可见和可搜索。
  2. 使用 filterColumn 手动处理添加列的搜索。
  3. 这样声明:
{data: 'added_column', name: 'actual_column_name'}

感谢您的快速回复@yajra

我已经在尝试第二个解决方案,但我注意到查询中没有考虑这个添加的列。

有什么想法吗 ?

确保您没有在该列上添加searchable: false

这就是我添加列->addColumn('company_name', function($deal) { return $deal->company_name; })

全局搜索查询为$dataTable->filterColumn('company_name', 'where', "like", ["%$keyword%"]);

我们可以在后端传递searchable: false吗?

searchable: false在客户端js。

BTW,你用的是什么版本?

喔好吧。 所以我们还是需要用你说的第一种方式,用这种方式。
我正在使用v6.17.0

不幸的是,我遇到了与@AshishGupta001相同的问题,因为该列不可排序,因此客户端技巧并没有解决它。
我已经探索了 filterColumn 替代方案,但也无法让它工作。
使用“yajra/laravel-datatables-oracle”:“~9.0”

控制器方法:

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

刀片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" },
          ]
        });

例外:尝试搜索或排序时:

yajraIssue

事实证明,该异常的问题是我的错; 我的 filterColumn 方法中有一个双 '$$' 符号。
yajra_issue_fix_1

但这并没有解决我的排序问题。 我仍然需要知道:

  1. 如何使列可排序
  2. 如何搜索和排序相关列再看一下文档为我的用例清除了这一点

@seewhy17您可以使用orderColumn进行复杂排序。 但是,在您的情况下,按fullname订购已经是开箱即用的 afaik。

@seewhy17您可以使用orderColumn进行复杂排序。 但是,在您的情况下,按fullname订购已经是开箱即用的 afaik。

好吧,它没有,我猜 filterColumn 方法与模型上的评估器冲突,它基本上做同样的事情......我真的不知道。
我知道我通过向 js 添加name: lastname来使用它,因此它按姓氏过滤,而 filterColumn 方法是多余的

此页面是否有帮助?
0 / 5 - 0 等级