Link to home
Get AccessLog in
Avatar of Tanabe Saori
Tanabe SaoriFlag for Japan

asked on

convert array to json

How can I convert this array 

[
  "sid",
  "name",
  "Last Name",
  "email"
]

Open in new window

to this:

$('#example').DataTable( {
    data: data,
    columns: [
        { data: 'sid' },
        { data: 'name' },
        { data: 'Last Name' },
        { data: 'email' }
    ]
} );

Open in new window


ASKER CERTIFIED SOLUTION
Avatar of Michel Plungjan
Michel Plungjan
Flag of Denmark image

Link to home
membership
This content is only available to members.
To access this content, you must be a member of Experts Exchange.
Get Access
Avatar of Tanabe Saori

ASKER

Thanks!
however, I think I have to do the $.document thing later, as the page, at this point, isn't generated.
I created a global variable
var MyCols = {};

Open in new window

can I put the results into that and use the $.document later.
sorry for being so dense. I'm currently learning python and never improved my javascript skills.
That is highly unlikely with the code you have provided


I tried to create a datatable but I need an example of your data

https://jsfiddle.net/mplungjan/h9z27q3e/

I think you need to give more information
OK.
I start with a query in PHP. following that, I switch to javascript and have a couple of functions that automatically create a table, with this one creating the headers:
<?PHP
//snippet from PHP query
$json = '[{"sid":"38","name":"Alex","Last Name":"hori","email":"noz@gmail.com"},{"sid":"59","name":"Andy","Last Name":"numa","email":"tommy@gmail.com"},{"sid":"40","name":"Ann","Last Name":"hama","email":"ohama@gmail.com"}]';
?>
<script type='text/javascript'>
var myList = <?= $json ?>;
var MyCols = {};
function addAllColumnHeaders(myList, selector) { 
var columnSet = []; 
var headerTr$ = $('<thead/>'); 
   for (var i = 0; 
   i < myList.length; 
   i++) { var rowHash = myList[i]; 
      for (var key in rowHash) { 
      if ($.inArray(key, columnSet) == -1) { columnSet.push(key); 
      headerTr$.append($('<th/>').html(key)); 
      } 
      } 
   }
   $(selector).append(headerTr$); 
   console.log("columnSet:");
   console.log(columnSet);
return columnSet; 
}
function buildHtmlTable(selector) { 
   var columns = addAllColumnHeaders(myList, selector);
   MCols = JSON.stringify(columns);
console.log(MCols);
   for (var i = 0; i < myList.length; i++) { var row$ = $('<tr/>'); 
      for (var colIndex = 0; 
      colIndex < columns.length; 
      colIndex++) { var cellValue = myList[i][columns[colIndex]]; 
      if (cellValue == null) cellValue = ""; 
      row$.append($('<td/>').html(cellValue)); 
   } 
   $(selector).append(row$); 
   } 
} 
</script>

Open in new window

This all works. But, I now want to use a more functional table setup, using datatables.net . However, they don't have the automatic headers, so I'm trying to export the ones in the format they expect; which is what started this question.
So, I put your code at the end of addallcolumnheaders, before the return:
const columns = columnSet.map(item => ({data:item}))
   console.log(columns);
//the next line, the problem is that the actual page hasn't been loaded yet.
   $('#example').DataTable( {
    data: data,
    columns: columns
} );

Open in new window

After the functions, I include the actual table-containing file:
<?PHP
include_once "../apex12/dt-data-sources.html"
?>

Open in new window

which includes, among other things,
<body onLoad="buildHtmlTable('#excelDataTable')">
<table id="excelDataTable" class="table table-striped table-bordered">
</table>
<table id="example" class="table table-striped table-bordered">
</table>
~~~~~~
<script src="app-assets/vendors/js/datatable/jquery.dataTables.min.js"></script>
<script src="app-assets/vendors/js/datatable/dataTables.bootstrap4.min.js"></script>
<script src="app-assets/js/data-tables/dt-data-sources.js"></script>
</body>

Open in new window


In dt-data-sources.jsare the lines :
$('#example').DataTable( {
    data: data,
    columns: [
        { data: 'sid' },
        { data: 'name' },
        { data: 'Last Name' },
        { data: 'email' }
    ]
} );

Open in new window

So, I was thinking of replacing that with MyCols so that I could put it in place. So far I've tried:
MyCols = ( {
    data: data,
    columns: columns
} );

Open in new window

but that generates an error data is not defined.
There, I think that covers it.

I do not see where you load "data" but  you could  move

const columns = columnSet.map(item => ({data:item}))
$('#example').DataTable( {
    data: data,
    columns: columns
} );

Open in new window


to the end of

function buildHtmlTable(selector) { 
  ....
  // here
}

Open in new window

ah, my mistake, data was supposed to be myList
tables are showing, but not the header names.
ah... you're going to hate me:
the data isn't data, it's title. like this:
$(".javascript-sourced").DataTable({
    data: myList,
    columns: [{
        title: "sid"
      },
      {
        title: "name"
      },
      {
        title: "Last Name"
      },
      {
        title: "email"
      }
    ]
  });

Open in new window

Ah, sorry I see it

https://jsfiddle.net/mplungjan/h9z27q3e/

It seems to work as expected now

const arr = [
  "sid",
  "name",
  "Last Name",
  "email"
]

const myList = [{"sid":"38","name":"Alex","Last Name":"hori","email":"noz@gmail.com"},{"sid":"59","name":"Andy","Last Name":"numa","email":"tommy@gmail.com"},{"sid":"40","name":"Ann","Last Name":"hama","email":"ohama@gmail.com"}]


const columns = arr.map(item => ({
  data: item
}))
console.log(columns)

$('#example').DataTable({
  data: myList,
  columns: columns
});

Open in new window

ah, my mistake, data was supposed to be myList
tables are showing, but not the header names.
ah... you're going to hate me:
the data isn't data, it's title. like this:
$(".javascript-sourced").DataTable({
    data: myList,
    columns: [{
        title: "sid"
      },
      {
        title: "name"
      },
      {
        title: "Last Name"
      },
      {
        title: "email"
      }
    ]
  });

Open in new window

It works with data, not title
I do not understand why you have the need to use title?
I suppose it's a requirement of the datatables.net js.
However, with the full json I gave as an example, it should work  with data. So, I'm experimenting some more.
One thing I noticed, which may be an issue, is that the map solution creates an array instead of a JSON structure.
Last night I tried to convert it, as a test using JSON.stringify, but was not successful.
I've tried to manually put both data and title info together in their JSON format. That kind-of worked, but the header and data columns don't align.
$('#example').DataTable( {
    data: myList,
    columns: [{title: 'sid'},{data:'sid'},{data:'name'},{title: 'name'},{data:'Last Name'},{title: 'Last Name'},{data:'email'},{title: 'email'}]
   } );

Open in new window

at this point I'm asking their forum. The main reason for using datatables.net is that it has sorting and export features.
I'll let you know the outcome.
Apologies for the trouble
I do not quite understand why this is not ok?

It is the output from the fiddle I posted above. I have just added the css too

User generated image
I removed the html-based 'head' section and the head doesn't get created.

I do not understand the comment. What was your expectation?

I can generate the thead from the JSON for you if you want:

https://jsfiddle.net/mplungjan/h9z27q3e/

$("#example").html(
  `<thead><tr>
    ${Object.keys(myList[0]).map(key => `<th>${key}</th>`)}
  </tr></thead>`);

Open in new window


Note I added

#example thead th  { text-transform: capitalize; }

Open in new window

Yes. What do I see and what do I need to do with this code?
It looks very similar to my datatable version but without the sorting etc
I'm gonna try (again) to mesh the two together. However (I use that word too much) I'm only going to use the code that generates the header. Then I'm going to use the code that feeds datatables.net to fill in the data. The problem is that datatables doesn't let you write back to the table to do it's  header fill (title), and when I try to combine the data and title into the same JSON, it makes the table wrong.

The only alternative I was trying to do before was simply 'layer' the datatables.net extras onto an already built table. I failed to figure that way out.
OK. I got that to work, by mixing your fiddle with mine. for some reason, yours still looks better and has the sort buttons.
But, I got one step much closer.
Good to hear.
I am still not sure what the problem is, but hope you can get it working or can explain more what is not working
The last bit of this is that, even though the table head is generated by addAllColumnHeaders, the sorting functionality doesn't show, like yours.
So, I hardwired the head like you did, then the sorting worked.

how can I make the javascript generated headers 'rendered'?
But in my last version I did NOT hardcode the table head
hmm. well, you got me the first part of this issue with the map solution.
and helped me figure out a few other quirks.
I'm going to accept that as the solution.
I'll post another related question, as this one has gone beyond the scope of the original question.
Thank you so much!
You are very welcome and thank you for the kind words elsewhere :)