2016-03-16 12 views
5

Próbuję pobrać DataTables do odczytu nazw kolumn ze źródła danych AJAX, ale wydaje się, że musi być coś, czego muszę tu nieobecno.DataTables - Dynamiczne kolumny ze źródła danych Ajax?

Zrobiłem skrzypce fiddle, w którym mogę ręcznie zdefiniować dane i kolumny używane przez tabelę.

tabela jest zadeklarowana w HTML i tam nie ma potrzeby, aby określić nazwy kolumn (<thead>..</thead>):

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

W JS możemy ręcznie zdefiniować dane:

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" ], 
]; 

Następnie ręcznie zdefiniuj nazwy kolumn lub tytuły:

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

Następnie, gdy inicjalizujemy tabelę po prostu zdać wcześniej zadeklarowanymi informacjami w poprzek na DataTables używać:

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

co skutkuje:

Resulting Table

Teraz moje pytanie brzmi: w jaki sposób mogę uzyskać to do pracy, jeżeli dane zawarte w AJAX server side response?

Próbowałem tego na różne sposoby i formy, ale nic nie wydaje się tu działać i walczę, aby znaleźć odpowiednią dokumentację na ten temat.

Na przykład jeżeli przetwarzanie po stronie serwera odesłać odpowiedź JSON, który zawiera nazwy kolumn na końcu:

{ 
    "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" 
    } 
    ] 
} 

Given to jest odpowiedź, próbowałem skonfigurować DataTables użyć źródła danych AJAX dla informacje rząd następująco:

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

Ale oczywiście columns jest niezdefiniowany tutaj.

więc uzyskać dane kolumn przed strony:

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

i przekazać je do DataTables jak wyżej. Ale tym razem wszystko, co otrzymuję podczas uruchamiania przykładu, to błąd w konsoli, który mówi: TypeError: p is undefined.

Więc jak mogę wykorzystać kolumny generowane dynamicznie, które są zwracane w odpowiedzi po stronie serwera? Czy nie ma prostszego sposobu, aby to osiągnąć?

EDIT:

DataTables edytor kodu do przetwarzania po stronie serwera/wygenerować odpowiedź JSON wymienionych powyżej:

<?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

Jaka jest odpowiedź 'text.php'? – CMedina

+0

@CMedina Witam ponownie! Odpowiedź jest jedynym JSON zawartym w pytaniu. Jest to po prostu normalna odpowiedź po stronie serwera, ale na końcu podałem nazwy kolumn w "kolumnach". Tak właśnie powracam jako obietnica i przechodzę do DT w "kolumnach: kolumnach". –

+0

To jest zabawny problem, znieść podczas pracy JSFiddle. – annoyingmouse

Odpowiedz

3

Jeśli nie skorzystać z wbudowanego w DataTables ajax powinno być dość łatwe biorąc pod uwagę struktura danych:

$(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 
      }); 
     } 
    }); 
}); 

Jak this JSFiddle, jesteś ograniczony następnie ładuje wszystkie dane na raz b ut, który nie powinien być wielkim problemem ... chyba że go zmienisz, uzyskasz kolumny z początkowego połączenia ajax i po zainicjowaniu DataTable dodaj wbudowany ajax - Nie próbowałem tego jednak ...

Powiązane problemy