Link to home
Start Free TrialLog in
Avatar of trevor1940
trevor1940

asked on

jQuery Datatables ajax with callback

Hi Following advise from here I'm attempting to build my table using Datatables

In the code bellow I get "TypeError: f is undefined  datatables.min.js (line 60, col 471)" so I'm clearly doing something wrong

I can't just load the data as I need to do stuff, I've added comments, while the data is loading I'm creating a Openlayers marker point (Outside this question scope)

The button is used to simulate the ajax call the table will need to be refreshed

Could someone give me a hand first fixing the error second how to get at & manipulate the data, as commented

<!DOCTYPE html>
<html>
  <head>
    <title>Data Tables</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    	<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.15/fc-3.2.2/fh-3.1.2/rr-1.2.0/sc-1.4.2/datatables.min.css"/>
 
<script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.15/fc-3.2.2/fh-3.1.2/rr-1.2.0/sc-1.4.2/datatables.min.js"></script>

<script type='text/javascript'>
	$(function() {
      // jQuery
       $('button').on('click', function (){
          var link = "MOCK_DATA.json";
//          $('#MainTable tbody').html(table);
          $('#dTable').DataTable({
            "ajax" : {
              "url": link,
              "data": function(json){
                      for ( var i=0, len=json.length ; i<len ; i++ ) {
                        
                        var ID = json[i][0];  // I need to assign the table row an ID eg. row_id = ID
                        var long = json[i][2]; // Use to locate on an openlayers map
                        var lat = json[i][3];  // dito
                        var MyURL =json[i][4]; // This need to be manipulated and returned as a valid url
                       console.log("long = " + long + "lat =" + lat);
                      }
                      return json;
                    }
              },
            
            scrollY : '200px', 
            scrollCollapse: true,
            paging: false,
            searching: false,
            info: false
          });
                    
        });
  
    });
    
</script>
  </head>
  <body>
  <div id=wrap>
      <button id="dummy" >Build Table</button>
   <div id=MainDiv>

      <table id="dTable" class="bordered static_headers">
        <thead>
          <tr>
            <td>id</td>
            <td>city</td>
            <td>long</td>
            <td>lat</td>
            <td>country_code</td>
            <td>url</td>
            <td>description</td>
          </tr>
        </thead>
        <tfoot>
        <tr>
          <td>id</td>
          <td>city</td>
          <td>long</td>
          <td>lat</td>
          <td>country_code</td>
          <td>url</td>
          <td>description</td>
        </tr>
        </tfoot>
      </table>
    </div>
   </div>
  </body>
</html>

Open in new window


MOCK_Data.json

[{"id":1,"name":"Irosin","Long":124.036411,"Lat":12.712478,"url":"http://dummyimage.com/135x216.bmp/dddddd/000000"},
{"id":2,"name":"Menongue","Long":17.6984879,"Lat":-14.6594083,"url":"http://dummyimage.com/149x135.png/cc0000/ffffff"},
{"id":3,"name":"Donglai","Long":126.154678,"Lat":41.654661,"url":"http://dummyimage.com/100x109.png/5fa2dd/ffffff"},
{"id":4,"name":"San Sebastian","Long":121.0519495,"Lat":14.7044701,"url":"http://dummyimage.com/114x212.bmp/dddddd/000000"},
{"id":5,"name":"Teutônia","Long":-51.7994632,"Lat":-29.4799379,"url":"http://dummyimage.com/247x178.bmp/dddddd/000000"},
{"id":6,"name":"Staroutkinsk","Long":59.3184961,"Lat":57.2287633,"url":"http://dummyimage.com/169x222.jpg/cc0000/ffffff"},
{"id":7,"name":"Molo","Long":35.7323709,"Lat":-0.2488358,"url":"http://dummyimage.com/242x164.bmp/cc0000/ffffff"},
{"id":8,"name":"Amnat Charoen","Long":99.855247,"Lat":12.0554892,"url":"http://dummyimage.com/115x148.png/dddddd/000000"},
{"id":9,"name":"Jinjiang","Long":118.552365,"Lat":24.781681,"url":"http://dummyimage.com/122x185.jpg/cc0000/ffffff"},
{"id":10,"name":"Sairam","Long":85.3117065,"Lat":27.6985161,"url":"http://dummyimage.com/117x156.jpg/cc0000/ffffff"}]

Open in new window

Avatar of Leonidas Dosas
Leonidas Dosas
Flag of Greece image

The return statement of the function must be an array with arrays inside. Each of these arrays must contains 6 values.

<!DOCTYPE html>
<html>
  <head>
    <title>Data Tables</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    	<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.15/fc-3.2.2/fh-3.1.2/rr-1.2.0/sc-1.4.2/datatables.min.css"/>
 
<script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.15/fc-3.2.2/fh-3.1.2/rr-1.2.0/sc-1.4.2/datatables.min.js"></script>


  </head>
  <body>
  <div id=wrap>
      <button id="dummy" >Build Table</button>
   <div id=MainDiv>

      <table id="dTable" class="bordered static_headers">
        <thead>
          <tr>
            <td>id</td>
            <td>city</td>
            <td>long</td>
            <td>lat</td>
            <td>country_code</td>
            <td>url</td>
            <td>description</td>
          </tr>
        </thead>
        <tfoot>
        <tr>
          <td>id</td>
          <td>city</td>
          <td>long</td>
          <td>lat</td>
          <td>country_code</td>
          <td>url</td>
          <td>description</td>
        </tr>
        </tfoot>
      </table>
    </div>
   </div>
   <script type='text/javascript'>
	$(function() {
      // jQuery
       $('button').on('click', function (){
          var link = "MOCK_DATA.json";
          //          $('#MainTable tbody').html(table);
          var arr=[];
          
          $('#dTable').DataTable({
            "ajax" : {
              "url": link,
               "dataSrc": function(json){
                      var leo=[];
                      for ( var i=0, len=json.length ; i<len ; i++ ) {                       
                        var ID = json[i].id;  // I need to assign the table row an ID eg. row_id = ID 
                        leo.push(ID);
                        var long = json[i].Long; // Use to locate on an openlayers map
                        leo.push(long);
                        var lat = json[i].Lat;  // dito
                        leo.push(lat);
                        var MyURL =json[i].url; // This need to be manipulated and returned as a valid url 
                        leo.push(MyURL);
//You must add 3 more key-values at json data at json file
                        leo.push('asd');
                        leo.push('fff');
                        leo.push('rrrrr');
                        arr.push(leo);                        
                        leo=[];
                        console.log("long = " + long + "lat =" + lat);
                      }
                      return arr;
                    }
              },
            
            scrollY : '200px', 
            scrollCollapse: true,
            paging: false,
            searching: false,
            info: false
          });
                    
        });
  
    });
    
</script>
  </body>
</html>

Open in new window

Firstly you need to make sure the number of columns in your datatable match the number of columns in your dataset.

Couple of other things. You need to assign columns from your data to columns of the DataTable. To manipluate the data you need to do it in the dataSrc function, not the data one:

$('#dTable').DataTable({
    "columns": [{ "data": "id" }, { "data": "name" }, { "data": "Lat" }, { "data": "Long" }, { "data": "url" }],
    "ajax": {
        "url": "data.json",
        "dataSrc" : function (json) {
            // loop through the json
            $.each(json, function(i, item) {
                // manipulate the data as you need to
                item.id = item.id * 2;
                item.name = item.name.toUpperCase();
            });
            // return the manipulated data
            return json;
        },
    },
    scrollY : '200px', 
    scrollCollapse: true,
    paging: false,
    searching: false,
    info: false
});

Open in new window

Avatar of trevor1940
trevor1940

ASKER

The return statement of the function must be an array with arrays inside. Each of these arrays must contains 6 values.

I assume the  6 values should relate to the table columns?  I had to play about getting the order right but I got it working

How do I  assign an id to the table row?
need to see the page to see whats going on
ok, some progress...

have a look at this...

added columns to initilialize, and removed extra columns from your table...

+ added jQuery of course!!!

https://jsfiddle.net/oc7ao3a0/

html
<div id=wrap>
  <button id="dummy">Build Table</button>
  <div id=MainDiv>

    <table id="dTable" class="bordered static_headers">
      <thead>
        <tr>
          <td>id</td>
          <td>city</td>
          <td>long</td>
          <td>lat</td>
          <!--<td>country_code</td>-->
          <td>url</td>
          <!--<td>description</td>-->
        </tr>
      </thead>
      <tfoot>
        <tr>
          <td>id</td>
          <td>city</td>
          <td>long</td>
          <td>lat</td>
          <!--<td>country_code</td>-->
          <td>url</td>
          <!--<td>description</td>-->
        </tr>
      </tfoot>
      <tbody></tbody>
    </table>
  </div>
</div>

Open in new window


JS
$(function() {

	  var myData = [{
	    "id": 1,
	    "name": "Irosin",
	    "Long": 124.036411,
	    "Lat": 12.712478,
	    "url": "http://dummyimage.com/135x216.bmp/dddddd/000000"
	  }, {
	    "id": 2,
	    "name": "Menongue",
	    "Long": 17.6984879,
	    "Lat": -14.6594083,
	    "url": "http://dummyimage.com/149x135.png/cc0000/ffffff"
	  }, {
	    "id": 3,
	    "name": "Donglai",
	    "Long": 126.154678,
	    "Lat": 41.654661,
	    "url": "http://dummyimage.com/100x109.png/5fa2dd/ffffff"
	  }, {
	    "id": 4,
	    "name": "San Sebastian",
	    "Long": 121.0519495,
	    "Lat": 14.7044701,
	    "url": "http://dummyimage.com/114x212.bmp/dddddd/000000"
	  }, {
	    "id": 5,
	    "name": "Teutônia",
	    "Long": -51.7994632,
	    "Lat": -29.4799379,
	    "url": "http://dummyimage.com/247x178.bmp/dddddd/000000"
	  }, {
	    "id": 6,
	    "name": "Staroutkinsk",
	    "Long": 59.3184961,
	    "Lat": 57.2287633,
	    "url": "http://dummyimage.com/169x222.jpg/cc0000/ffffff"
	  }, {
	    "id": 7,
	    "name": "Molo",
	    "Long": 35.7323709,
	    "Lat": -0.2488358,
	    "url": "http://dummyimage.com/242x164.bmp/cc0000/ffffff"
	  }, {
	    "id": 8,
	    "name": "Amnat Charoen",
	    "Long": 99.855247,
	    "Lat": 12.0554892,
	    "url": "http://dummyimage.com/115x148.png/dddddd/000000"
	  }, {
	    "id": 9,
	    "name": "Jinjiang",
	    "Long": 118.552365,
	    "Lat": 24.781681,
	    "url": "http://dummyimage.com/122x185.jpg/cc0000/ffffff"
	  }, {
	    "id": 10,
	    "name": "Sairam",
	    "Long": 85.3117065,
	    "Lat": 27.6985161,
	    "url": "http://dummyimage.com/117x156.jpg/cc0000/ffffff"
	  }];

	  $('button').on('click', function() {
	    $('#dTable').DataTable({
	      data: myData,
	      "columns": [{
	        "data": "id"
	      }, {
	        "data": "name"
	      }, {
	        "data": "Long"
	      }, {
	        "data": "Lat"
	      }, {
	        "data": "url"
	      }],
	      scrollY: '200px',
	      scrollCollapse: true,
	      paging: false,
	      searching: false,
	      info: false
	    });

	  });

	});

Open in new window

There are two ways to manipulate the id.
The first way is to get it from the json data eg:
[{"id":1,ect....},{"id":2,ect....},{"id":3,ect....}]

Open in new window

The other way is inside the for loop:
User generated image
You can add a row ID by usnig the fnRowCallback function:

$('#dTable').DataTable({
    "columns": [{ "data": "id" }, { "data": "name" }, { "data": "Lat" }, { "data": "Long" }, { "data": "url" }],
    "ajax": {
        "url": "data.json",
        "dataSrc" : function (json) {
            $.each(json, function(i, item) {
                item.id = item.id * 2;
                item.name = item.name.toUpperCase();
            });

            return json;
        },
    },
    "fnRowCallback": function(nRow, aData, iDisplayIndex) {
        // aData is the JSON for each row, so you can access the properties, such as  aData.Long, aData.name, aData.url, aData.id
        var rowId = "someID_" + aData.id; 
        nRow.setAttribute('id',rowId);
    },
    scrollY : '200px', 
    scrollCollapse: true,
    paging: false,
    searching: false,
    info: false
});

Open in new window

@ Chris is there an ajax fail or error handle?

Where might I include a binding function to handle url click events once the datatable is drawn?


If it possible to draw the table something like this but still be able to highlight move the 2 rows together like you suggested here
User generated image
The Example given isn't obvious how to achieve this

<table border="1" id="dTable" class="bordered static_headers">
        <thead>
          <tr>
            <th>id</th>
            <th>city</th>
            <th>long</th>
            <th>lat</th>
            <th>country_code</th>
            <th>url</th>
           
          </tr>
        </thead>
        <tr>
          <td>1</td>
          <td>London</td>
          <td>0</td>
          <td>52</td>
          <td>UK</td>
          <td>google.co.uk</td>
          
        </tr>
        <tr>
          <th>description</th>
          <td colspan="5">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mattis pellentesque scelerisque. Proin vel elit.</td>
        </tr>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I thought I closed this sorry for delay

I used Chris example so I guess he wins