Laravel:按显示的数据或枚举排序和搜索,而不是按数据库 table
Laravel: Sort and search by data displayed or enum, not by database table
我正在使用 Laravel 5.6 和 yajira 数据表插件。
我想在其中一列中显示用户状态,它是数据库中 0-5 之间的数字,但我想在列中将其显示为单词(新建、更新、初始等。 )
制作数据表的方法:
public function usersDatatable()
{
$query = User::with('jobrole')->select([
'users.id',
'users.first_name',
'users.last_name',
'users.email',
'users.postcode',
'users.preferred_role_id',
'users.status',
]);
return Datatables::of($query)
->addColumn('jobrole', function (User $user) {
return $user->jobrole ? str_limit($user->jobrole->role, 30, '...') : '';
})
->addColumn('status', function (User $user) {
return $user->status_name;
})
->addColumn('action', function (User $user) {
return '<a href="' . route('users.show',$user->id).'" class="btn btn-sm btn-primary"><i class="fa fa-eye"></i></a>';
})
->make(true);
}
如您所见,status
返回为 $user->status_name
,这是我的用户模型上的访问器方法:
public function getStatusNameAttribute()
{
return UserStatus::getDescription($this->status);
}
而 UserStatus 枚举 class 具有将状态从数字转换为字符串的逻辑:
namespace App\Enums;
use BenSampo\Enum\Enum;
final class UserStatus extends Enum
{
const Initial = 0;
const New = 1;
const Updated = 2;
const Synced = 3;
const Ignore = 4;
/**
* Get the description for an enum value
*
* @param int $value
* @return string
*/
public static function getUserStatus(int $value): string
{
switch ($value) {
case self::Initial:
return 'Initial';
break;
case self::New:
return 'New';
break;
case self::Updated:
return 'Updated';
break;
case self::Synced:
return 'Synced';
break;
case self::Ignore:
return 'Ignore';
break;
default:
return self::getKey($value);
}
}
}
在视图中,我通过 jQuery Ajax 和数据表获取数据,我在视图中的代码在这里:
$('#users-table').DataTable({
processing: true,
serverSide: true,
ajax: '{!! route('users') !!}',
columns: [
{ data: 'id', width: '10', name: 'users.id' },
{ data: null, render:function (data, type, row) {
return data.last_name+', '+data.first_name;
}, name: 'users.last_name'
},
{ data: 'email', name: 'users.email' },
{ data: 'postcode', name: 'users.postcode' },
{ data: 'jobrole', name: 'jobrole.role' },
{ data: 'status', name: 'user.status' },
{ data: 'action', width: '10', name: 'action', orderable: false, searchable: false}
]
});
现在,由于 name:user.status
,搜索和排序将基于仅包含数字的 user.status
列。有没有办法强制它使用显示的数据进行搜索和订购?请给我指明正确的方向。
public function usersDatatable()
{
$query = User::with('jobrole')->select([
'users.id',
'users.first_name',
'users.last_name',
'users.email',
'users.postcode',
'users.preferred_role_id',
'users.status',
]);
return Datatables::of($query)
->addColumn('jobrole', function (User $user) {
return $user->jobrole ? str_limit($user->jobrole->role, 30, '...') : '';
})
->addColumn('status', function (User $user) {
return $user->status_name;
})
->addColumn('status', function ($user) {
if ($user->status == 1) {
return "New";
} elseif ($user->status == 2) {
return "Updated";
} else {
return "Pending";
}
})
->addColumn('action', function (User $user) {
return '<a href="' . route('users.show',$user->id).'" class="btn btn-sm btn-primary"><i class="fa fa-eye"></i></a>';
})
->make(true);
}
解决方案 1
如果您可以查找 table 用户状态(类似于 jobrole
),那将是最好的,您可以加入该查询以获取状态名称。
解决方案 2
在你的情况下,我会让代码生成原始 CASE ... WHEN
子句。
例如:
$query = User::with('jobrole')->select([
'users.id',
'users.first_name',
'users.last_name',
'users.email',
'users.postcode',
'users.preferred_role_id',
\DB::raw("
(
CASE
WHEN status=0 THEN 'Initial'
WHEN status=1 THEN 'New'
WHEN status=2 THEN 'Updated'
WHEN status=3 THEN 'Synced'
WHEN status=4 THEN 'Ignore'
ELSE ''
END
) AS status_name
")
]);
然后删除 addColumn('status')
语句。
然后在JavaScript中使用{ data: 'status_name', name: 'status_name' }
。
请注意,使用 CASE ... WHEN
可能会影响性能。
解决方案 3
或者,您可以使用 filterColumn()
方法根据给定关键字过滤数字列。
您只能使用此解决方案按数字状态进行排序。
解决方案 4
或者,您可以通过删除 serverSide: true
选项来使用 client-side 处理,并让 jQuery 数据表执行 sorting/filtering。您不需要 yajra 数据tables,只需 return 对象数组作为 JSON 字符串。
这可能更简单,但它适用于几千条记录以下的小型数据集。
我正在使用 Laravel 5.6 和 yajira 数据表插件。
我想在其中一列中显示用户状态,它是数据库中 0-5 之间的数字,但我想在列中将其显示为单词(新建、更新、初始等。 )
制作数据表的方法:
public function usersDatatable()
{
$query = User::with('jobrole')->select([
'users.id',
'users.first_name',
'users.last_name',
'users.email',
'users.postcode',
'users.preferred_role_id',
'users.status',
]);
return Datatables::of($query)
->addColumn('jobrole', function (User $user) {
return $user->jobrole ? str_limit($user->jobrole->role, 30, '...') : '';
})
->addColumn('status', function (User $user) {
return $user->status_name;
})
->addColumn('action', function (User $user) {
return '<a href="' . route('users.show',$user->id).'" class="btn btn-sm btn-primary"><i class="fa fa-eye"></i></a>';
})
->make(true);
}
如您所见,status
返回为 $user->status_name
,这是我的用户模型上的访问器方法:
public function getStatusNameAttribute()
{
return UserStatus::getDescription($this->status);
}
而 UserStatus 枚举 class 具有将状态从数字转换为字符串的逻辑:
namespace App\Enums;
use BenSampo\Enum\Enum;
final class UserStatus extends Enum
{
const Initial = 0;
const New = 1;
const Updated = 2;
const Synced = 3;
const Ignore = 4;
/**
* Get the description for an enum value
*
* @param int $value
* @return string
*/
public static function getUserStatus(int $value): string
{
switch ($value) {
case self::Initial:
return 'Initial';
break;
case self::New:
return 'New';
break;
case self::Updated:
return 'Updated';
break;
case self::Synced:
return 'Synced';
break;
case self::Ignore:
return 'Ignore';
break;
default:
return self::getKey($value);
}
}
}
在视图中,我通过 jQuery Ajax 和数据表获取数据,我在视图中的代码在这里:
$('#users-table').DataTable({
processing: true,
serverSide: true,
ajax: '{!! route('users') !!}',
columns: [
{ data: 'id', width: '10', name: 'users.id' },
{ data: null, render:function (data, type, row) {
return data.last_name+', '+data.first_name;
}, name: 'users.last_name'
},
{ data: 'email', name: 'users.email' },
{ data: 'postcode', name: 'users.postcode' },
{ data: 'jobrole', name: 'jobrole.role' },
{ data: 'status', name: 'user.status' },
{ data: 'action', width: '10', name: 'action', orderable: false, searchable: false}
]
});
现在,由于 name:user.status
,搜索和排序将基于仅包含数字的 user.status
列。有没有办法强制它使用显示的数据进行搜索和订购?请给我指明正确的方向。
public function usersDatatable()
{
$query = User::with('jobrole')->select([
'users.id',
'users.first_name',
'users.last_name',
'users.email',
'users.postcode',
'users.preferred_role_id',
'users.status',
]);
return Datatables::of($query)
->addColumn('jobrole', function (User $user) {
return $user->jobrole ? str_limit($user->jobrole->role, 30, '...') : '';
})
->addColumn('status', function (User $user) {
return $user->status_name;
})
->addColumn('status', function ($user) {
if ($user->status == 1) {
return "New";
} elseif ($user->status == 2) {
return "Updated";
} else {
return "Pending";
}
})
->addColumn('action', function (User $user) {
return '<a href="' . route('users.show',$user->id).'" class="btn btn-sm btn-primary"><i class="fa fa-eye"></i></a>';
})
->make(true);
}
解决方案 1
如果您可以查找 table 用户状态(类似于 jobrole
),那将是最好的,您可以加入该查询以获取状态名称。
解决方案 2
在你的情况下,我会让代码生成原始 CASE ... WHEN
子句。
例如:
$query = User::with('jobrole')->select([
'users.id',
'users.first_name',
'users.last_name',
'users.email',
'users.postcode',
'users.preferred_role_id',
\DB::raw("
(
CASE
WHEN status=0 THEN 'Initial'
WHEN status=1 THEN 'New'
WHEN status=2 THEN 'Updated'
WHEN status=3 THEN 'Synced'
WHEN status=4 THEN 'Ignore'
ELSE ''
END
) AS status_name
")
]);
然后删除 addColumn('status')
语句。
然后在JavaScript中使用{ data: 'status_name', name: 'status_name' }
。
请注意,使用 CASE ... WHEN
可能会影响性能。
解决方案 3
或者,您可以使用 filterColumn()
方法根据给定关键字过滤数字列。
您只能使用此解决方案按数字状态进行排序。
解决方案 4
或者,您可以通过删除 serverSide: true
选项来使用 client-side 处理,并让 jQuery 数据表执行 sorting/filtering。您不需要 yajra 数据tables,只需 return 对象数组作为 JSON 字符串。
这可能更简单,但它适用于几千条记录以下的小型数据集。