Laravel-datatables: Cómo crear una fila secundaria / un detalle secundario

Creado en 8 may. 2015  ·  9Comentarios  ·  Fuente: yajra/laravel-datatables

Como dice el título, cómo crear una fila secundaria para obtener información adicional como este ejemplo usando estos complementos: D
https://www.datatables.net/examples/api/row_details.html

Atentamente

Comentario más útil

Así es como lo hice todo desde mi controlador, espero que esto ayude a alguien que no quiera la implementación de js, en realidad estamos llamando a js pero desde nuestro controlador laravel,

$model = User::all();
if (request()->ajax()) {
   return DataTables::make($model)
    ->addIndexColumn()
    ->addColumn('handleBarColumn',function(User $userData){
            return view('admin.pages.forms.handleBarInfo',compact('userData'));
    })
    ->rawColumns(['handleBarColumn'])
        ->toJson();
}
$html = $builder->columns([
       ['title' => '','className' => 'details-control','orderable'  => false, 'data' => null,'searchable' => false,'defaultContent' => '','width' => '20px'],
    // ['data' => 'DT_RowIndex', 'name' => 'DT_RowIndex', 'title' => '#','orderable' => 'false','searchable' => 'false'],
       ['data' => 'email', 'name' => 'email', 'title' => 'Email'],
       ['data' => 'handleBarColumn', 'name' => 'handleBarColumn', 'title' => '','visible' => false,'orderable'  => false]
  ])->parameters([
            'dom'           => 'Bfrtip',
            'paging'        => true,
            'searching'     => true,
            'info'          => true,
            'buttons'       => [ 'csv' , 'excel' , 'pdf'],
            'order'         => [1,'asc'],
            'drawCallback' => 'function () {
                function format ( d ) {
                    return d.handleBarColumn;
                }
                let table = $("#formDataTables").DataTable();
                $("#formDataTables tbody").on("click", "td.details-control", function () {
                    let tr = $(this).closest("tr");
                    let row = table.row( tr );
                    if ( row.child.isShown() ) {
                        row.child.hide();
                        tr.removeClass("shown");
                    }
                    else {
                        row.child(format(row.data())).show();
                        tr.addClass("shown");
                    }
                });
            }',
        ]);

Ahora, finalmente, dentro del archivo blade (que en mi caso es "admin> pages> forms> handleBarInfo.blade.php") puede escribir cualquier condición que desee

{{ $userData->email }}

Y aquí está mi archivo de índice donde se representan todas las tablas de datos

@extends('admin.layout.app')

@section('content')
    <div class="ibox">
        <div class="ibox-content">
            <div class="row">
                <div class="col-md-12">
                    <div class="table-responsive">
                    {!! $html->table(['class' => 'table table-striped table-bordered', 'id' => 'formDataTables']) !!}
                    </div>
                </div>
            </div>
        </div>
    </div>
<strong i="12">@endsection</strong>
@section('styles')
    <style>
        #formDataTables tbody td.details-control {
            background-image: url('{{ asset('assets/admin/images/details_open.png') }}');
            cursor: pointer;
            background-repeat:  no-repeat;
            background-position: center;
            background-origin: content-box;
            background-size: cover;
            padding: 7px;
        }
        #formDataTables tbody tr.shown td.details-control {
            background-image: url('{{ asset('assets/admin/images/details_close.png') }}');
            cursor: pointer;
            background-repeat:  no-repeat;
            background-position: center;
            background-origin: content-box;
            background-size: cover;
            padding: 7px;
        }

        #formDataTables tbody tr .rowDetails p {
            font-size: 14px;
            font-weight: 800;
            float: left;
            margin-right: 10px;
            padding: 1px;
            margin-bottom: 0;
        }
        #formDataTables tbody tr .rowDetails a{

        }
        #formDataTables tbody tr .rowDetails td{
            padding: 5px;
        }
        .m-r-10{
            margin-right: 10px !important;
        }
    </style>
<strong i="13">@endsection</strong>
@section('scripts')
    {!! $html->scripts() !!}
<strong i="14">@endsection</strong>

Todos 9 comentarios

Hola,

Simplemente siga lo que muestra ese enlace en el lado de JavaScript y debería funcionar como se esperaba. La única diferencia en ese ejemplo es que tendrá que usar el script del lado del servidor de DT.

Por otro lado, creo que agregaré esto en la aplicación de demostración en la que he estado trabajando últimamente. Lo mantendremos informado aquí cuando la demostración de Detalles de fila esté lista. Compruébelo también para ver cómo se usa el paquete en ciertos escenarios.

¡Salud!

A continuación se muestra un script de ejemplo que puede utilizar para implementar esto.

var table = $('#users-table').DataTable({
        processing: true,
        serverSide: true,
        ajax: '{{ url("users-data") }}',
        columns: [
            {
                "className":      'details-control',
                "orderable":      false,
                "data":           null,
                "defaultContent": ''
            },
            {data: 'id', name: 'id'},
            {data: 'name', name: 'name'},
            {data: 'email', name: 'email'},
            {data: 'created_at', name: 'created_at'},
            {data: 'updated_at', name: 'updated_at'}
        ],
        order: [[1, 'asc']]
    });

    // Add event listener for opening and closing details
    $('#users-table tbody').on('click', 'td.details-control', function () {
        var tr = $(this).closest('tr');
        var row = table.row( tr );

        if ( row.child.isShown() ) {
            // This row is already open - close it
            row.child.hide();
            tr.removeClass('shown');
        }
        else {
            // Open this row
            row.child( format(row.data()) ).show();
            tr.addClass('shown');
        }
    });

    /* Formatting function for row details - modify as you need */
    function format ( d ) {
        // `d` is the original data object for the row
        return '<table class="table">'+
            '<tr>'+
                '<td>Full name:</td>'+
                '<td>'+d.name+'</td>'+
                '</tr>'+
            '<tr>'+
                '<td>Email:</td>'+
                '<td>'+d.email+'</td>'+
                '</tr>'+
            '<tr>'+
                '<td>Extra info:</td>'+
                '<td>And any further details here (images etc)...</td>'+
                '</tr>'+
            '</table>';
    }

En tu controlador

public function getUsersData()
{
        $users = User::select(['id', 'name', 'email', 'created_at', 'updated_at']);

        return Datatables::of($users)->make(true);
}

Terminado de agregar el ejemplo de detalles de fila en la aplicación de demostración, solo compruébalo para ver cómo funciona. ¡Gracias!

No estoy seguro del error js, pero debería tener algo como esto en su script. Usando la plantilla de la barra de control y luego pase los datos template(row.data()) .

var template = Handlebars.compile($("#details-template").html());

// Add event listener for opening and closing details
    $('#users-table tbody').on('click', 'td.details-control', function () {
        var tr = $(this).closest('tr');
        var row = table.row( tr );

        if ( row.child.isShown() ) {
            // This row is already open - close it
            row.child.hide();
            tr.removeClass('shown');
        }
        else {
            // Open this row
            row.child( template(row.data()) ).show();
            tr.addClass('shown');
        }
    });

Sí, lo siento, el código funciona, solo necesito eliminar los otros datos después de la 'acción',
Se puede hacer clic en el detalle en el lado izquierdo de la tabla, el problema es que el ícono no se muestra. Sin embargo, ya descargue el botón de su demostración:?

Creo que el CSS aún no se ha insertado.
Mi mal, gracias por la respuesta rápida: +1:

Así es como lo hice todo desde mi controlador, espero que esto ayude a alguien que no quiera la implementación de js, en realidad estamos llamando a js pero desde nuestro controlador laravel,

$model = User::all();
if (request()->ajax()) {
   return DataTables::make($model)
    ->addIndexColumn()
    ->addColumn('handleBarColumn',function(User $userData){
            return view('admin.pages.forms.handleBarInfo',compact('userData'));
    })
    ->rawColumns(['handleBarColumn'])
        ->toJson();
}
$html = $builder->columns([
       ['title' => '','className' => 'details-control','orderable'  => false, 'data' => null,'searchable' => false,'defaultContent' => '','width' => '20px'],
    // ['data' => 'DT_RowIndex', 'name' => 'DT_RowIndex', 'title' => '#','orderable' => 'false','searchable' => 'false'],
       ['data' => 'email', 'name' => 'email', 'title' => 'Email'],
       ['data' => 'handleBarColumn', 'name' => 'handleBarColumn', 'title' => '','visible' => false,'orderable'  => false]
  ])->parameters([
            'dom'           => 'Bfrtip',
            'paging'        => true,
            'searching'     => true,
            'info'          => true,
            'buttons'       => [ 'csv' , 'excel' , 'pdf'],
            'order'         => [1,'asc'],
            'drawCallback' => 'function () {
                function format ( d ) {
                    return d.handleBarColumn;
                }
                let table = $("#formDataTables").DataTable();
                $("#formDataTables tbody").on("click", "td.details-control", function () {
                    let tr = $(this).closest("tr");
                    let row = table.row( tr );
                    if ( row.child.isShown() ) {
                        row.child.hide();
                        tr.removeClass("shown");
                    }
                    else {
                        row.child(format(row.data())).show();
                        tr.addClass("shown");
                    }
                });
            }',
        ]);

Ahora, finalmente, dentro del archivo blade (que en mi caso es "admin> pages> forms> handleBarInfo.blade.php") puede escribir cualquier condición que desee

{{ $userData->email }}

Y aquí está mi archivo de índice donde se representan todas las tablas de datos

@extends('admin.layout.app')

@section('content')
    <div class="ibox">
        <div class="ibox-content">
            <div class="row">
                <div class="col-md-12">
                    <div class="table-responsive">
                    {!! $html->table(['class' => 'table table-striped table-bordered', 'id' => 'formDataTables']) !!}
                    </div>
                </div>
            </div>
        </div>
    </div>
<strong i="12">@endsection</strong>
@section('styles')
    <style>
        #formDataTables tbody td.details-control {
            background-image: url('{{ asset('assets/admin/images/details_open.png') }}');
            cursor: pointer;
            background-repeat:  no-repeat;
            background-position: center;
            background-origin: content-box;
            background-size: cover;
            padding: 7px;
        }
        #formDataTables tbody tr.shown td.details-control {
            background-image: url('{{ asset('assets/admin/images/details_close.png') }}');
            cursor: pointer;
            background-repeat:  no-repeat;
            background-position: center;
            background-origin: content-box;
            background-size: cover;
            padding: 7px;
        }

        #formDataTables tbody tr .rowDetails p {
            font-size: 14px;
            font-weight: 800;
            float: left;
            margin-right: 10px;
            padding: 1px;
            margin-bottom: 0;
        }
        #formDataTables tbody tr .rowDetails a{

        }
        #formDataTables tbody tr .rowDetails td{
            padding: 5px;
        }
        .m-r-10{
            margin-right: 10px !important;
        }
    </style>
<strong i="13">@endsection</strong>
@section('scripts')
    {!! $html->scripts() !!}
<strong i="14">@endsection</strong>

Así es como lo hice todo desde mi controlador, espero que esto ayude a alguien que no quiera la implementación de js, en realidad estamos llamando a js pero desde nuestro controlador laravel,

$model = User::all();
if (request()->ajax()) {
   return DataTables::make($model)
  ->addIndexColumn()
  ->addColumn('handleBarColumn',function(User $userData){
          return view('admin.pages.forms.handleBarInfo',compact('userData'));
  })
  ->rawColumns(['handleBarColumn'])
        ->toJson();
}
$html = $builder->columns([
       ['title' => '','className' => 'details-control','orderable'  => false, 'data' => null,'searchable' => false,'defaultContent' => '','width' => '20px'],
    // ['data' => 'DT_RowIndex', 'name' => 'DT_RowIndex', 'title' => '#','orderable' => 'false','searchable' => 'false'],
       ['data' => 'email', 'name' => 'email', 'title' => 'Email'],
       ['data' => 'handleBarColumn', 'name' => 'handleBarColumn', 'title' => '','visible' => false,'orderable'  => false]
  ])->parameters([
            'dom'           => 'Bfrtip',
            'paging'        => true,
            'searching'     => true,
            'info'          => true,
            'buttons'       => [ 'csv' , 'excel' , 'pdf'],
            'order'         => [1,'asc'],
            'drawCallback' => 'function () {
                function format ( d ) {
                    return d.handleBarColumn;
                }
                let table = $("#formDataTables").DataTable();
                $("#formDataTables tbody").on("click", "td.details-control", function () {
                    let tr = $(this).closest("tr");
                    let row = table.row( tr );
                    if ( row.child.isShown() ) {
                        row.child.hide();
                        tr.removeClass("shown");
                    }
                    else {
                        row.child(format(row.data())).show();
                        tr.addClass("shown");
                    }
                });
            }',
        ]);

Ahora, finalmente, dentro del archivo blade (que en mi caso es "admin> pages> forms> handleBarInfo.blade.php") puede escribir cualquier condición que desee

{{ $userData->email }}

Y aquí está mi archivo de índice donde se representan todas las tablas de datos

@extends('admin.layout.app')

@section('content')
    <div class="ibox">
        <div class="ibox-content">
            <div class="row">
                <div class="col-md-12">
                    <div class="table-responsive">
                    {!! $html->table(['class' => 'table table-striped table-bordered', 'id' => 'formDataTables']) !!}
                    </div>
                </div>
            </div>
        </div>
    </div>
<strong i="13">@endsection</strong>
@section('styles')
    <style>
        #formDataTables tbody td.details-control {
            background-image: url('{{ asset('assets/admin/images/details_open.png') }}');
            cursor: pointer;
            background-repeat:  no-repeat;
            background-position: center;
            background-origin: content-box;
            background-size: cover;
            padding: 7px;
        }
        #formDataTables tbody tr.shown td.details-control {
            background-image: url('{{ asset('assets/admin/images/details_close.png') }}');
            cursor: pointer;
            background-repeat:  no-repeat;
            background-position: center;
            background-origin: content-box;
            background-size: cover;
            padding: 7px;
        }

        #formDataTables tbody tr .rowDetails p {
            font-size: 14px;
            font-weight: 800;
            float: left;
            margin-right: 10px;
            padding: 1px;
            margin-bottom: 0;
        }
        #formDataTables tbody tr .rowDetails a{

        }
        #formDataTables tbody tr .rowDetails td{
            padding: 5px;
        }
        .m-r-10{
            margin-right: 10px !important;
        }
    </style>
<strong i="14">@endsection</strong>
@section('scripts')
    {!! $html->scripts() !!}
<strong i="15">@endsection</strong>

¿Podemos poner ajax dentro de nuestro controlador php? como lo haces, estás llamado js dentro del controlador. ¿Es posible si ponemos ajax dentro de js en el controlador?

Sé que esto es antiguo, pero solo para mencionar, @vipertecpro , su implementación tiene un error porque drawCallback se ejecuta en cada recarga de la tabla, por lo que cuando carga su página, funciona como se esperaba. Si recarga su tabla de datos (no toda la página), se ejecuta de nuevo, por lo que se ejecuta dos veces (mostrar-ocultar) al hacer clic (y la información no se muestra). Si vuelve a cargar, se ejecuta tres veces y se muestra la información (mostrar-ocultar-mostrar) y así sucesivamente ....

Creo que deberías usar 'initComplete' para esto.

¿Fue útil esta página
0 / 5 - 0 calificaciones