Laravel Yajra 数据表呈现自定义 html/列样式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42337764/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 15:22:19  来源:igfitidea点击:

Laravel Yajra datatables rendering custom html / column styling

jqueryhtmllaraveldatatablesrendering

提问by Birdy

I have spent a fair few days researching datatables and yajra package, That said I am no closer to getting the result I need and would greatly appreciate a helping hand on this one if anyone with more knowledge than my novice approach!

我花了几天时间研究数据表和 yajra 包,也就是说我离得到我需要的结果还很远,如果有人比我的新手方法有更多的知识,我将不胜感激!

To help explain better I have attached two images, First image is of an application that already has this implemented and second is a quick mock I have thrown up to show the difference.

为了更好地解释,我附上了两张图片,第一张图片是一个已经实现了这个的应用程序,第二张是我抛出的一个快速模拟来显示差异。



The desired outcome I am hoping to achieve... enter image description here

我希望达到的预期结果...... 在此处输入图片说明



The present view I have...enter image description here

目前的观点我...在此处输入图片说明



I'm basically trying to add custom html to each column that requires the functionality.. I have managed to achieve some slight success by returning a custom array like so:

我基本上是在尝试将自定义 html 添加到需要该功能的每个列中..通过返回一个自定义数组,我设法取得了一些小小的成功,如下所示:

foreach ($tasks as $task) {
    $checkBox = '<div class="checkbox"><input type="checkbox" value="63"><label></label></div>';
    $taskPriority = '<span class="text-info inline-block">Medium</span>';
            ... so on ...
    $row = array(
        $checkBox,
        $taskPriority,
        ... so on ...
    );
    $rows[] = $row;
}
$list['data'] = $rows;
return $list;

While this works I would not say its the best approach and one imagines there is some what a better and more elegant way of doing this?

虽然这行得通,但我不会说它是最好的方法,有人认为有什么更好、更优雅的方法可以做到这一点?

I understand yajra has the addColumn and editColumn methods, I have used these to add an action column as that is the only one that seems to render any html, Any other method other than addColumn('action', 'blah blah') seems not to want to render the html and instead displays it as raw text in the row.

我知道 yajra 有 addColumn 和 editColumn 方法,我用它们来添加一个动作列,因为这是唯一一个似乎呈现任何 html 的方法,除了 addColumn('action', 'blah blah') 之外的任何其他方法似乎都没有想要呈现 html,而是将其显示为行中的原始文本。

Just in case this is to help anyone, here is the Ajax call made to get the table data.

以防万一这是对任何人的帮助,这里是获取表数据的 Ajax 调用。

$('#taskstable').DataTable({
    "processing": true,
    "retrieve": true,
    "serverSide": true,
    'paginate': true,
    'searchDelay': 700,
    "bDeferRender": true,
    "responsive": true,
    "autoWidth": false,
    "pageLength": 5,
    "lengthMenu": [[5, 10, 25, 50, 100], [5, 10, 25, 50, 100]],
    ajax: '/tasks/get-tasks'
});

Hopefully someone can help relieve the stress of being a novice! Thanks.

希望有人能帮助减轻作为新手的压力!谢谢。

回答by vinod bhandary

bro i can you some idea this may help you to get your desired result. Controller:

兄弟,我能给你一些想法,这可能会帮助你得到你想要的结果。控制器:

public function index(Request $request)
    {
        $data = [];
        $data['page_title'] = trans($this->trans_path . 'general.page.index.page-title');
        $data['show_modal'] = false;
        $data['trans_path'] = $this->trans_path;
        if ($request->get('add') && $request->get('add') == "true") {
            $data['show_modal'] = true;
        }

        // TODO: Confirm this logic
        //count no. of promoter admin
        $data['promoter'] = User::where('user_type', AclHelper::getUsersTypeKey('promoter-admin'))->count();

        // for mapping policy
        $data['admin_user_model'] = new AdminUser();

        //generate add Button
        $data['add_btn_html'] = view($this->loadDefaultVars($this->view_path . '.partials._promoter_add_button'))->render();
        $data['assignable_user_roles'] = $this->getAssignableRolesByAuthUser();

        return view($this->loadDefaultVars($this->view_path . '.index'), compact('data'));
    }

    public function search(Request $request)
    {

        $data = [];
        $columns = ['rud.*', 'us.first_name as promoter_first_name', 'us.last_name as promoter_last_name', 'users.email', 'users.username',
            'r.name', 'r.display_name', 'rud.created_by', 'rud.promoter_id', 'users.enabled'];
        $users = $this->getUserListJoinQuery($columns)
            ->leftJoin('role_users_details as us', 'rud.promoter_id', '=', 'us.id')
            ->groupBy('users.id');

        if (in_array(AclHelper::getUsersTypeKey('super-admin'), AclHelper::getUserRoles(), 1) ||
            in_array(AclHelper::getUsersTypeKey('support-admin'), AclHelper::getUserRoles(), 1)
        ) {
            $users->where('users.id', '!=', auth()->user()->id);
            $data['users'] = $users->get();
        } else {

            if (in_array(AclHelper::getUsersTypeKey('promoter-admin'), AclHelper::getUserRoles(), 1))
                $data['users'] = $users->where('rud.promoter_id', Auth::user()->id)->get();
            elseif (in_array(AclHelper::getUsersTypeKey('promoter-editor'), AclHelper::getUserRoles(), 1)) {
                $promoter_id = Auth::user()->userDetail->promoter_id;
                $users->where('r.name', '!=', AclHelper::getUsersTypeKey('promoter-editor'));
                $data['users'] = $users->where('rud.promoter_id', $promoter_id)->get();
            } else {
                return response('Unauthorized request made.', 401);
            }
        }

        return Datatables::of($data['users'])
            ->editColumn('user_id', function ($users) {
                $data = view($this->loadDefaultVars($this->view_path . '.partials._action_fields'), compact('users'))->render();
                return $data;
            })
            ->editColumn('profile_image', function ($users) {
                if (!isset($users->profile_image)) {
                    return "";
                }
                return '<img src="' . asset(config('neptrox.admin_user_path.thumbnail') . $users->profile_image) .
                '" alt="' . $users->first_name . '" style="height: 40px;" >';
            })
            ->editColumn('name', function ($users) {
                return $users->first_name . ' ' . $users->middle_name . ' ' . $users->last_name;
            })
            ->editColumn('gender', function ($users) {
                if ($users->gender === 'male')
                    return 'Male';
                elseif ($users->gender === 'female')
                    return 'Female';
                else
                    return 'Other';
            })
            ->editColumn('user_type', function ($users) {
//                return $users->pivot->display_name;
                return config('neptrox.admin-users-roles.' . $users->name . '.title');
            })
            ->editColumn('promoter', function ($users) {
                return $users->promoter_first_name . ' ' . $users->promoter_last_name;
            })
            ->editColumn('status', function ($users) {
                if ($users->enabled === 1) {
                    return "<span class='text-success'> " .
                    '<i class="fa fa-check-circle-o text-info"></i>' .
                    "</span>";
                }
                return "<span class='text-danger'>" .
                '<i class="fa fa-ban text-danger"></i>' .
                "</span>";
            })
            ->make(true);

    }

jquery Scripts

jQuery 脚本

<script src="https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js" type="text/javascript"></script>
<script>

    (function (options) {

        var route_url = options.dataTableConfigVariable.route_url;
        var columns = options.dataTableConfigVariable.columns;
        var order = options.dataTableConfigVariable.orderColumn;
        if (order == 'undefined' || order == null || order == "") {
            order = 1;
        }
        var config = {
            "dom": '<t>' +
            '<"card-footer card-pagination"<"row"<"col-md-8"p><"col-md-4 form-design1 right"l>>>',
            "oLanguage": {
                "sLengthMenu": " _MENU_ ",
                "sSearchPlaceholder": "Search",
                "oPaginate": {
                    "sNext": "<span aria-hidden='true'>?</span><span class='sr-only'>Next</span>",
                    "sPrevious": "<span aria-hidden='true'>?</span><span class='sr-only'>Previous</span>"
                },
            },
            processing: true,
            serverSide: true,
            ajax: {
                type: 'POST',
                url: route_url.dataTable_url,
                data: {
                    _token: $('meta[name=csrf-token]').attr("content")
                }
            },
            columns: columns,
            'order': [[order, 'asc']]
        };

        //initialize dataTables
        var table = $('table.table').DataTable(config);

        $('#searchField').keyup(function(){
            table.search($(this).val()).draw() ;
        });


        //Enables or disables the performer and reload the ajax after success
        $('body').on('click', '.enableDisable', function (e) {
            e.preventDefault();
            var url = $(this).attr('href');
            $.ajax({
                type: 'GET',
                url: url,
                success: function (response) {
                    table.ajax.reload(null, false);
                }
            });
        });

        //toggle all checkbox checked or unchecked
        $('body').on('click', 'input[name="checkAll"]', function () {
            var checkBoxes = $("input[name=checkbox\[\]]");
            checkBoxes.prop("checked", $(this).prop("checked"));
        });

        //enable selected performers
        $('body').on('click', '#enable', function (e) {
            var url = route_url.enableAll;
            enableDisablePerformer(e, url);
        });

        //disable selected performers
        $('body').on('click', '#disable', function (e) {
            var url = route_url.disableAll;
            enableDisablePerformer(e, url);
        });

        function enableDisablePerformer(e, url) {
            e.preventDefault();
            var formData = $('input[name^=checkbox]');
            var data = {};
            formData.each(function (index) {
                if ($(this).is(':checked')) {
                    data[index] = $(this).val();
                }
            });
            $.ajax({
                type: 'POST',
                url: url,
                data: {
                    _token: $('meta[name=csrf-token]').attr("content"),
                    id: data
                },
                success: function (response) {
                    if (response == 'ok') {
                        table.ajax.reload(null, false);
                        $('body').find('input[name="checkAll"]').prop('checked', false);
                    }
                }
            });
        }


        //Delete confirmation popup
        $('body').on('click', '.try-sweet-warningConfirm', function () {
            var id = $(this).attr('id');
            swal({
                title: "{{ trans($trans_path.'general.delete.sure') }}",
                text: "{{ trans($trans_path.'general.delete.message') }}",
                type: "warning",
                showCancelButton: true,
                confirmButtonColor: "{{ trans($trans_path.'general.delete.confirmButtonColor') }}",
                confirmButtonText: "{{ trans('general.button.delete') }}",
                cancelButtonText: "{{ trans('general.button.cancel') }}",
                closeOnConfirm: true
            }, function (isConfirm) {
                if (isConfirm) {
                    $.ajax({
                        type: 'POST',
                        url: route_url.delete,
                        data: {
                            _token: $('meta[name=csrf-token]').attr("content"),
                            id: id
                        },
                        success: function (response) {
                            table.row($(this).closest('tr')).remove().draw();
                            if (response == 'ok') {
                                swal({
                                    title: "{{ trans($trans_path.'general.status.delete') }}",
                                    text: "{{ trans($trans_path.'general.status.deleted') }}",
                                    type: "success",
                                    timer: 2000,
                                    confirmButtonColor: "{{ trans($trans_path.'general.delete.confirmButtonColor') }}"
                                });
                            }
                        }
                    });

                }
            });
        });

        //Delete bulk confirmation popup
        $('body').on('click', '#delete', function () {
            swal({
                title: "{{ trans($trans_path.'general.delete.sure') }}",
                text: "{{ trans($trans_path.'general.delete.message') }}",
                type: "warning",
                showCancelButton: true,
                confirmButtonColor: "{{ trans($trans_path.'general.delete.confirmButtonColor') }}",
                confirmButtonText: "{{ trans('general.button.delete') }}",
                cancelButtonText: "{{ trans('general.button.cancel') }}",
                closeOnConfirm: true
            }, function (isConfirm) {
                if (isConfirm) {
                    var url =route_url.delete;
                    deleteBulkPerformer(url);
                    $('body').find('input[name="checkAll"]').prop('checked', false);
                    swal({
                        title: "{{ trans($trans_path.'general.status.delete') }}",
                        text: "{{ trans($trans_path.'general.status.deleted') }}",
                        type: "success",
                        timer: 2000,
                        confirmButtonColor: "{{ trans($trans_path.'general.delete.confirmButtonColor') }}"
                    });
                }
            });
        });

        function deleteBulkPerformer(url){
            var formData = $('input[name^=checkbox]');

            var data = {};
            formData.each(function (index) {
                if ($(this).is(':checked')) {
                    data[index] = $(this).val();
                }
            });
            $.ajax({
                type: 'POST',
                url: url,
                data: {
                    _token: $('meta[name=csrf-token]').attr("content"),
                    id: data,
                    bulk: 'bulk'
                },
                success: function (response) {
                    if (response == 'ok') {
                        table.row($(this).closest('tr')).remove().draw();
                    }
                }
            });
        }

    })({dataTableConfigVariable:dataTableConfigVariable});

</script>

View Page

查看页面

 <script>
        var dataTableConfigVariable = {
            route_url: {
                dataTable_url:  '{{route("admin.admin_users.search")}}',
                enableAll: '{{route("admin.admin_users.enableAll")}}',
                disableAll: '{{route("admin.admin_users.disableAll")}}',
                delete: '{{route("admin.admin_users.delete")}}'
            },
            columns: [
                {data: 'user_id', name: 'user_id', orderable: false, searchable: false},
                {data: 'profile_image', name: 'profile_image', orderable: false, searchable: false},
                {data: 'name', name: 'name'},
                {data: 'user_code', name: 'user_code', orderable: false},
                {data: 'email', name: 'email'},
                {data: 'username', name: 'username'},
                {data: 'gender', name: 'gender'},
                {data: 'user_type', name: 'user_type'},
                {data: 'promoter', name: 'promoter', orderable: false, searchable: false},
                {data: 'status', name: 'status', orderable: false, searchable: false},
            ],
            orderColumn: 2
        };
    </script>

回答by Birdy

The easiest approach I have found as of the time I post this answer is as follows, That being said I am sure this is not the best approach to take and maybe in time to come someone with more experience than myself will be able to post a better solution.

在我发布此答案时,我找到的最简单的方法如下,话虽如此,我确信这不是最好的方法,也许及时出现比我更有经验的人将能够发布更好的解决方案。



In my project I am using a specific package called Laravel Collective that can be found: ...here..

在我的项目中,我使用了一个名为 Laravel Collective 的特定包,可以找到: ...here..

Using this package gives you access to a helper class and facade. With some slight modification that is specific to my application i have been able to make great use of this package.

使用这个包可以让你访问一个辅助类和外观。通过一些特定于我的应用程序的轻微修改,我已经能够充分利用这个包。

One similar approach would be to do this:

一种类似的方法是这样做:

public function getTasks()
{
    $tasks = $this->taskInterface->model()->all();
    return $this->datatables->collection($tasks)
        ->editColumn('name', function ($model) {
            return HtmlFacade::link("admin/tasks/{$model->id}", $model->name);
        })
        ->addColumn('action', function($query) {
            return view('backend.global.tables.actions.all-tasks-actions', compact('query'));
        })
        ->make(true);
}

Note

笔记

when using the return HtmlFacade::link(); method this will return html that gets rendered on the data table, A full list of methods can be found by looking at the documentation or in my case going through the class its self and seeing the source code gave me a better understanding of how their package worked, Not only that but it gives the ability to add further methods to the class and that's how I have come to get the outcome I required.

当使用返回 HtmlFacade::link(); 方法这将返回呈现在数据表上的 html,可以通过查看文档或在我的情况下通过类本身找到完整的方法列表并查看源代码让我更好地了解他们的包有效,不仅如此,它还提供了向类添加更多方法的能力,这就是我获得所需结果的方式。

I am not going to post all the custom classes as I don't think it is too relevant to helping anyone in the future as the methods I have added or very similar to what the package comes with out of the box, the only difference is to allow for onclick JavaScript events and incline CSS.

我不打算发布所有自定义类,因为我认为这对将来帮助任何人没有太大意义,因为我添加的方法或与开箱即用的软件包非常相似,唯一的区别是允许 onclick JavaScript 事件和倾斜 CSS。

The moral of this answer is to let anyone else in a similar position to myself know that if you are already using this package then its possible you do not need to cast all rows to arrays manually just to pass custom html to the view and I no longer need to do this:

这个答案的寓意是让其他与我处于类似位置的人知道,如果您已经在使用这个包,那么您可能不需要手动将所有行转换为数组,只是为了将自定义 html 传递给视图,我不需要不再需要这样做:

 $rows = [];
 $checkBox = '<div class="checkbox"><input type="checkbox" value="63"><label></label></div>';
 $taskPriority = '<span class="text-info inline-block">Medium</span>';
 ect... As seen in original post..

instead you can pass custom attributes, classes and build up from the laravel collective package, Here is the link method laravel collective comes with that can be a building block to adding custom methods to their package.

相反,您可以传递自定义属性、类并从 laravel 集合包中构建,这是 laravel 集合附带的链接方法,它可以作为向包中添加自定义方法的构建块。

public function link($url, $title = null, $attributes = [], $secure = null, $escape = true)
{
    $url = $this->url->to($url, [], $secure);

    if (is_null($title) || $title === false) {
        $title = $url;
    }

    if ($escape) {
        $title = $this->entities($title);
    }

    return $this->toHtmlString('<a href="' . $url . '"' . $this->attributes($attributes) . '>' . $title . '</a>');
}

That should give people an idea of how you can easily modify this Html Builder to your requirements, As I said I am sure this is not the best and most elegant want of achieving the same if not better outcome so I will leave the question open for future solutions I just thought I would share my solution.

这应该让人们了解如何轻松地根据您的要求修改此 Html Builder,正如我所说,我确信这不是实现相同甚至更好结果的最佳和最优雅的愿望,因此我将这个问题留给未来的解决方案我只是想我会分享我的解决方案。