Laravel-datatables: Como renderizar 2 tabelas de dados em uma página em guias diferentes

Criado em 12 jun. 2017  ·  9Comentários  ·  Fonte: yajra/laravel-datatables

Resumo do problema ou solicitação de recurso


Oi, bom dia para você.
Quero perguntar uma coisa e preciso da sua ajuda, criei uma página que tinha 2 abas, a aba #um está mostrando dados por dia, a aba # dois está mostrando dados por hora, tento fazer a mesma tabela nessas duas abas, mas é só mostrando na aba # um, na aba # dois mostrando apenas o nome da coluna, por que isso aconteceu?

Fragmento de código do problema

Suspeitei que algo errado está no meu controlador, este é o código:

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

então eu quero perguntar como renderizar várias tabelas de dados no controlador.
Obrigada.
Ah, e este é o código em meu 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>

Detalhes do sistema

Por favor, inclua esses detalhes sobre o seu sistema! Se forem omitidos, o tíquete perderá a prioridade em relação às solicitações / tíquetes de outros usuários.
  • Sistema operacional: Ubuntu 16.04
  • Versão PHP: 7
  • Versão do Laravel: 5.2
  • Versão do Laravel-Datatables: 6.0
question

Comentários muito úteis

Forro "Um":

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

também tenha cuidado com ajax minimizado, adicione dados ajax após chamar este método.

Todos 9 comentários

No entanto, não gosto muito de usar a abordagem baseada em serviços para uma mesa, diferente para outra. Para consistência, gostaria de saber como separar ainda mais ... é possível criar tal estrutura ?:

UsersDatatableController
cuida exclusivamente da tabela de dados para usuários
a visualização serve apenas para renderizar a tabela de dados e manipular a solicitação de ajax

PostsDatatableController
cuida exclusivamente da tabela de dados para postagens (gerais ou relacionadas aos usuários)
a visualização serve apenas para renderizar a tabela de dados e manipular a solicitação de ajax

UsersController
Faça uso de UsersDatatableController e PostsDatatableController para renderizar e colocá-los na mesma visão, em abas, sobrescritos, o que for .. chamadas ajax das tabelas de dados não seriam tratadas por este controlador. A previsão desse controlador também pode ser para um formulário de edição em vez de uma página normal, com uma tabela de dados dentro dela.

Uma vez que meu caso de uso é para renderizar tabela de dados do lado do servidor, procurando combinar com
https://github.com/imanghafoori1/laravel-widgetize
e isto
https://stackoverflow.com/questions/41857905/using-laravel-controllers-as-components-to-build-a-view

@yajra
Deixe-me saber seus pensamentos thx

@isometriq atm, acho que você não pode usar duas classes DataTable na mesma rota para o tratamento de Ajax por padrão. No entanto, talvez você possa adicionar parâmetros adicionais que podem ser usados ​​para identificar qual resposta ajax está sendo solicitada.

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

Você pode então usar o construtor para ambos DT em sua visualização.

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

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

Apenas uma ideia que você pode explorar. Obrigado!

Obrigado @yajra, vou tentar algumas coisas

Obrigado por esta pergunta. Acabei de fazer isso funcionar conforme sugeriu @yajra . Para pessoas que estão tentando fazer a mesma coisa e acessaram esta postagem, o arquivo de visualização deve ser:

{!! $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

Você precisa passar um atributo de id único para cada tabela para que o js funcione corretamente. Espero que ajude alguém!

E em sua classe DataTable, você passou o parâmetro adicional no método html ():

public function html() {

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

@yajra , seria bom se a documentação mais recente em https://datatables.yajrabox.com/services/two-datatables tivesse este exemplo.

@benlwong obrigado pelo feedback. O código-fonte de demonstração está disponível aqui . Se você puder, não hesite em enviar um PR. Obrigado!

Olá a todos, Segui a solução deste post e consegui meus dois datatables funcionando ao mesmo tempo!
Mas .. não quero que carreguem os dois ao mesmo tempo, quando a página geral estiver sendo carregada.

Quero que carregue a 2ª tabela de dados quando clicar em uma guia / botão específico.
Eu vi isso na página: 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']]
        });
    }
}

Isso consiste basicamente em adicionar uma instrução if envolvendo o JS da tabela de dados, mas eu quero uma solução através da implementação do DataTable Service, como você estava fazendo neste post. Algo assim:

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

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

    }
}

Mas isso não pode ser feito porque a função "scripts ()" imprime as tags

Questões relacionadas

MahdiPishguy picture MahdiPishguy  ·  17Comentários

baig772 picture baig772  ·  14Comentários

Yahav picture Yahav  ·  16Comentários

fanjavaid picture fanjavaid  ·  32Comentários

jay-shah-rushiinfotech picture jay-shah-rushiinfotech  ·  19Comentários