2016-03-16 36 views
5

Sto cercando di ottenere DataTables per leggere i nomi delle colonne da un'origine dati AJAX ma sembra che ci sia qualcosa che devo mancare qui.DataTable - Colonne dinamiche da origine dati Ajax?

Ho creato un violino fiddle in cui posso definire manualmente i dati e le colonne utilizzate dalla tabella.

La tabella è dichiarata nel codice HTML e non c'è alcuna necessità di definire i nomi delle colonne (<thead>..</thead>):

<table id="example" class="display table table-striped table-bordered" 
     cellspacing="0" width="100%"></table> 

Nel JS definiamo manualmente i dati:

var data = [ 
    [ "Row 1 - Field 1", "Row 1 - Field 2", "Row 1 - Field 3" ], 
    [ "Row 2 - Field 1", "Row 2 - Field 2", "Row 2 - Field 3" ], 
]; 

Poi definire manualmente i nomi oi titoli delle colonne:

var columns = [ 
    { "title":"One" }, 
    { "title":"Two" }, 
    { "title":"Three" } 
]; 

Quindi quando inizializzare la tabella abbiamo semplicemente passare le informazioni precedentemente dichiarato tutta per DataTable da utilizzare:

$(document).ready(function() { 
    $('#example').DataTable({ 
    dom: "Bfrtip", 
    data: data, 
    columns: columns 
    }); 
}); 

che si traduce in:

Resulting Table

Ora la mia domanda è: come faccio a farlo funzionare se i dati è incluso nel il AJAX server side response?

Ho provato questo in vari modi e forme, ma nulla sembra davvero funzionare qui e sto combattendo per trovare la relativa documentazione su questo.

Per esempio, se l'elaborazione lato server rimandati una risposta JSON che comprende i nomi delle colonne alla fine:

{ 
    "data": [ 
    { 
     "id": "1", 
     "One": "Row 1 - Field 1", 
     "Two": "Row 1 - Field 2", 
     "Three": "Row 1 - Field 3" 
    }, 
    { 
     "id": "2", 
     "One": "Row 2 - Field 1", 
     "Two": "Row 2 - Field 2", 
     "Three": "Row 2 - Field 3" 
    } 
    ], 
    "options": [], 
    "files": [], 
    "columns": [ 
    { 
     "title": "One", 
     "data": "One" 
    }, 
    { 

     "title": "Two", 
     "data": "Two" 
    }, 
    { 
     "title": "Three", 
     "data": "Three" 
    } 
    ] 
} 

Dato questo è la risposta, ho provato a configurare DataTable di utilizzare una fonte di dati AJAX per le informazioni della riga come segue:

$(document).ready(function() { 
    $('#example').DataTable({ 
    dom: "Bfrtip", 
    "ajax": '/test.php', 
    columns: columns 
    }); 
}); 

Ma ovviamente columns è definito qui.

in modo da ottenere i dati della colonna prima di mano:

function getPromise() { 
    var deferred = $.Deferred(); 
    var dataUrl = document.location.origin+'/text.php'; 
    $.getJSON(dataUrl, function(jsondata) { 
    setTimeout(function() { 
     deferred.resolve(jsondata); 
    }, 0); 
    }).fail(function(jqxhr, textStatus, error) { 
    // ********* FAILED 
    var err = textStatus + ", " + error; 
    console.log("Request Failed: " + err); 
    }); 
    return deferred.promise(); 
} 
// Get the columns 
getPromise().done(function(jsondata) { 
    columns = jsondata.columns; 
    console.log(columns); 
}); 

e passarlo al DataTable come sopra. Ma questa volta tutto ciò che ottengo nell'esecuzione dell'esempio è un errore nella console che dice TypeError: p is undefined.

Quindi, in che modo è possibile utilizzare le colonne generate dinamicamente che vengono restituite nella risposta lato server? Non c'è un modo più semplice per raggiungere questo obiettivo?

EDIT:

DataTable codice Editor per l'elaborazione lato server/per generare la risposta JSON di cui sopra:

<?php 
// DataTables PHP library 
require_once '/path/to/DataTables.php'; 

// Alias Editor classes so they are easy to use 
use 
    DataTables\Editor, 
    DataTables\Editor\Field, 
    DataTables\Editor\Format, 
    DataTables\Editor\Mjoin, 
    DataTables\Editor\Upload, 
    DataTables\Editor\Validate; 

// Build our Editor instance and process the data coming from _POST 
$out = Editor::inst($db, 'example') 
    ->fields(
    Field::inst('id')->set(false), 
    Field::inst('`One`')->validator('Validate::notEmpty'), 
    Field::inst('`Two`')->validator('Validate::notEmpty'), 
    Field::inst('`Three`')->validator('Validate::notEmpty') 
) 
    ->process($_POST) 
    ->data(); 

// On 'read' remove the DT_RowId property so we can see fully how the `idSrc` 
// option works on the client-side. 
if (Editor::action($_POST) === Editor::ACTION_READ) { 
    for ($i=0, $ien=count($out['data']) ; $i<$ien ; $i++) { 
     unset($out['data'][$i]['DT_RowId']); 
    } 
} 

// Create the thead data 
if (count ($out) > 0) { 
    $columns = array(); 
    foreach ($out['data'][0] as $column=>$relativeValue) { 
    // Add all but the id value 
    if ($column !== 'id') { 
     // Add this column name 
     $columns[] = array(
     "title"=>$column, 
     "data"=>$column 
    ); 
    } 
    } 
} 
// Add the the thead data to the ajax response 
$out['columns'] = $columns; 
// Send the data back to the client 
echo json_encode($out); 
+0

Qual è la risposta di 'text.php'? – CMedina

+0

@CMedina Ciao ancora! La risposta è l'unico JSON incluso nella domanda. Quindi è solo la normale risposta lato server, ma alla fine ho incluso i nomi delle colonne all'interno di "colonne". Quindi questo è ciò che sto tornando come promessa e passando a DT in 'columns: columns'. –

+0

Questo è un problema divertente, sopportare mentre lavoro su un JSFiddle. – annoyingmouse

risposta

3

Se non si utilizza il costruito nel DataTables ajax dovrebbe essere abbastanza facile dato la struttura dei dati:

$(document).ready(function() { 
    $.ajax({ 
     type: 'POST', 
     dataType: 'json', 
     url: '/echo/json/', 
     data: { 
      json: JSON.stringify(jsonData) 
     }, 
     success: function(d) { 
      $('#example').DataTable({ 
       dom: "Bfrtip", 
       data: d.data, 
       columns: d.columns 
      }); 
     } 
    }); 
}); 

Come this JSFiddle, sei limitato poi a caricare tutti i dati in una sola volta b Questo non dovrebbe essere un grosso problema ... a meno che tu non lo modifichi prendi le colonne dalla chiamata iniziale ajax e una volta che il DataTable è iniziato, aggiungi il built-in ajax - Non ho provato questo però ...

Problemi correlati