Laravel-datatables: Как отобразить 2 данных на одной странице на разных вкладках

Созданный на 12 июн. 2017  ·  9Комментарии  ·  Источник: yajra/laravel-datatables

Краткое изложение проблемы или запроса функции


Привет, добрый день.
Я хочу кое-что спросить и нуждаюсь в вашей помощи, я создал страницу с 2 вкладками, вкладка #one показывает данные за день, вкладка #two показывает данные за час, я пытаюсь создать ту же таблицу на этих двух вкладках, но это только отображается на вкладке #one, на вкладке #2 отображается только имя столбца, почему это происходит?

Фрагмент кода проблемы

Я подозревал, что в моем контроллере что-то не так, это код:

public function index(InsightDataTable $dataTable)
    {
        return $dataTable->render('admin.report.insight.index');
    }

поэтому я хочу спросить, как отобразить несколько данных в контроллере.
Спасибо.
О, и это код в моем index.blade.php

@section('content')
    @include('admin.notification')
    <div class="row">
            <div class="col-xs-12">

                <div class="nav-tabs-custom">
                    <ul class="nav nav-tabs">
                        <li class="hari"><a href="#hari" data-toggle="tab">Hari</a></li>
                        <li class="jam"><a href="#jam" data-toggle="tab">Jam</a></li>
                    </ul>
                    <div class="tab-content">

                        <div class="hari tab-pane" id="hari">
                        <div class="row">
                <div class="btn-group pull-right" style="margin: 0 15px 15px 0;">
                    <a href="" class="btn btn-primary btn-header" id="export_file">{{ trans('label.download_excel') }}</a> 
                </div>
            </div>
                <div class="box">
                <div class="box-body">
                <table border="0" cellspacing="5" cellpadding="5">
                        <tbody>
                            <tr>
                                <td>Period:&nbsp;</td>
                                <td>
                                    <input type="text" class="form-control date-range" id="" style="width: 180px;text-align: center;">
                                </td>
                            </tr>
                        </tbody>
                    </table>
                    <br/>
                    {!! $dataTable->table(['class' => 'datatable table table-striped', 'cellspacing'=>"0", 'width'=>"100%"]) !!}
                </div>
            </div>
                        </div>

                      <div class="jam tab-pane" id="jam">
                            <div class="row">
                <div class="btn-group pull-right" style="margin: 0 15px 15px 0;">
                    <a href="" class="btn btn-primary btn-header" id="export_file">{{ trans('label.download_excel') }}</a> 
                </div>
            </div>
                <div class="box">
                <div class="box-body">
                <table border="0" cellspacing="5" cellpadding="5">
                        <tbody>
                            <tr>
                                <td>Period:&nbsp;</td>
                                <td>
                                    <input type="text" class="form-control date-range" id="" style="width: 180px;text-align: center;">
                                </td>
                            </tr>
                        </tbody>
                    </table>
                    <br/>
                    {!! $dataTable->table(['class' => 'datatable table table-striped', 'cellspacing'=>"0", 'width'=>"100%"]) !!}
                </div>
            </div>
                      </div>

                    </div>
                  </div>
                </div>

            </div>
<strong i="16">@endsection</strong>

@section('custom_js')
    <script> 
        dateSelection = false;
        $('.date-range').daterangepicker();
        $('.date-range').on('apply.daterangepicker', function(ev, picker) {
            $('#dataTableBuilder').on('preXhr.dt', function ( e, settings, data ) {
                data.firstDate = picker.startDate.format('YYYY-MM-DD');
                data.lastDate = picker.endDate.format('YYYY-MM-DD');
                merge_date = data.firstDate+'_'+data.lastDate;
            });       
            var table = $('#dataTableBuilder').DataTable();
           table.ajax.reload();
           dateSelection =true;                 
        });

        $("#export_file").click(function() {
            if(dateSelection == false) {
                window.location.href = "{{ url('admin/report/insight/export/all') }}";
            } else {
                window.location.href = "{{ url('admin/report/insight/export') }}/"+merge_date;
            }
            return false;
        });

    </script>
    {!! $dataTable->scripts() !!}
<strong i="17">@endsection</strong>

Детали системы

Пожалуйста, укажите эти сведения о вашей системе! Если они не указаны, билет будет лишен приоритета над запросами / билетами других пользователей.
  • Операционная система: Ubuntu 16.04
  • Версия PHP: 7
  • Версия Laravel: 5.2
  • Версия Laravel-Datatables: 6.0
question

Самый полезный комментарий

"Один лайнер:

    public function show(PrimaryDataTable $primaryDataTable, SecondDataTable $secondDataTable)
    {
        /**  Depend request we need to match proper class */
        return ${request()->get('table', 'primary') . 'DataTable'}->render(
            'resource.show',
            compact('primaryDataTable', 'secondDataTable')
        );
    }

также будьте осторожны с минимизированным ajax, добавьте данные ajax после вызова этого метода.

Все 9 Комментарий

Однако мне не очень нравится использовать сервисный подход для одной таблицы, а не для другой. Для единообразия хотелось бы знать, как еще разделить .. можно ли создать такую ​​структуру ?:

UsersDatatableController
исключительно заботится о данных для пользователей
представление предназначено только для рендеринга данных и обработки запроса ajax

PostsDatatableController
исключительно заботится о данных для сообщений (общих или связанных с пользователями)
представление предназначено только для рендеринга данных и обработки запроса ajax

UsersController
Используйте UsersDatatableController и PostsDatatableController для рендеринга и разместите их в одном и том же представлении, на вкладках, в нижней части, где угодно .. Вызовы таблиц данных ajax не будут обрабатываться этим контроллером. Представление об этом контроллере может также быть для формы редактирования вместо обычной страницы с данными внутри нее.

Поскольку мой вариант использования предназначен для рендеринга данных на стороне сервера, я хочу объединить с
https://github.com/imanghafoori1/laravel-widgetize
и это
https://stackoverflow.com/questions/41857905/using-laravel-controllers-as-components-to-build-a-view

@yajra
Дай мне знать твои мысли, спасибо

@isometriq atm, я думаю, вы не можете использовать два класса DataTable в одном маршруте для обработки ajax по умолчанию. Однако, возможно, вы можете добавить дополнительный параметр, который вы можете использовать, чтобы определить, какой ответ ajax запрашивается.

public function index(UsersDatatable $udt, PostsDatatable $pdt) {
  if (request()->get('table') == 'posts') {
    return $udt->render('my.view', compact('udt', 'pdt'));
  }

  return $pdt->render('my.view', compact('udt', 'pdt'));
}

Затем вы можете использовать построитель для обоих DT в вашем представлении.

{!! $udt->html()->table() !!} // users table
{!! $pdt->html()->table() !!} // posts table

{!! $udt->scripts() !!} // users table scripts
{!! $pdt->scripts() !!} // posts table scripts

Просто идея, которую вы можете попробовать изучить. Спасибо!

Спасибо, @yajra, я попробую пару вещей

Спасибо за этот вопрос. Я просто заставил это работать, как предложил @yajra . Для людей, которые пытаются сделать то же самое и попали на этот пост, файл представления должен быть:

{!! $udt->html()->table(['id' => 'udt']) !!} // users table
{!! $pdt->html()->table(['id' => 'pdt']) !!} // posts table

{!! $udt->html()->scripts() !!} // users table scripts
{!! $pdt->html()->scripts() !!} // posts table scripts

Вам необходимо передать уникальный атрибут id в каждую таблицу, чтобы js работал правильно. Надеюсь, это кому-нибудь поможет!

И в вашем классе DataTable вы передали дополнительный параметр в методе html ():

public function html() {

    return $this->builder()
        ->ajax(['data' => 'function(d) { d.table = "posts"; }'])
        ->parameters($this->getBuilderParameters());
}

@yajra , было бы неплохо, если бы в последней документации на https://datatables.yajrabox.com/services/two-datatables был этот пример.

@benlwong благодарит за отзыв. Исходный код демонстрации доступен здесь . Если можете, не стесняйтесь отправлять PR. Спасибо!

Привет всем, я следил за решением в этом посте, и мои две таблицы данных работали одновременно!
Но .. я не хочу, чтобы они загружались одновременно, когда загружается общая страница.

Я хочу, чтобы загружалась вторая таблица данных, когда я нажимаю определенную вкладку / кнопку.
Я видел это на странице: https://datatables.yajrabox.com/services/two-datatables

function postsDataTables() {
    if (!$.fn.dataTable.isDataTable('#postsTable')) {
        $('#postsTable').DataTable({
            dom: 'Bfrtip',
            processing: true,
            serverSide: true,
            order: [[0, 'desc']],
            buttons: [
                'csv', 'excel', 'pdf', 'print', 'reset', 'reload'
            ],
            ajax: '/services/two-datatables/posts',
            columns: [
                {data: 'id', name: 'posts.id'},
                {data: 'title', name: 'posts.title'},
                {data: 'created_by', name: 'users.name', width: '110px'},
                {data: 'created_at', name: 'posts.created_at', width: '120px'},
                {data: 'updated_at', name: 'posts.updated_at', width: '120px'},
            ],
            order: [[0, 'desc']]
        });
    }
}

Это в основном состоит в добавлении оператора if, обертывающего JS datatable, но мне нужно решение через реализацию DataTable Service, как вы делали в этом посте. Что-то вроде этого:

function postsDataTables() {
    if (!$.fn.dataTable.isDataTable('#postsTable')) {

        {!! $secondDataTable->html()->scripts() !!}

    }
}

Но это невозможно сделать, потому что функция "scripts ()" печатает теги