Laravel:按显示的数据或枚举进行排序和搜索,而不是按数据库表进行排序和搜索

时间:2018-03-15 11:16:03

标签: javascript php laravel datatables laravel-datatables

我正在使用Laravel 5.6和yajira datatables插件。

我想在其中一列中显示用户状态,该列是数据库中0-5的数字,但我想在列中显示并显示为单词,(New,Updated,Initial等)< / p>

制作数据表的方法:

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返回,这是我的用户模型上的Accessor方法:

public function getStatusNameAttribute()
    {
        return UserStatus::getDescription($this->status);
    }

UserStatus Enum类具有从数字到字符串的状态转换逻辑:

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列。有没有办法强制它使用显示的数据进行搜索和排序?请指出我正确的方向。

2 个答案:

答案 0 :(得分:2)

解决方案1 ​​

如果你有一个用户状态查找表(类似于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选项来使用客户端处理,并让jQuery DataTables进行排序/过滤。你不需要yajra数据表,只需将对象数组作为JSON字符串返回。

这可能更简单,但它适用于几千条记录下的小型数据集。

答案 1 :(得分:0)

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