Creating table from API - javascript

My function is pulling information from an api and then putting it into the table. For some reason this function is not working.
this is my function:
function getPayInfo(socCode) {
var apiurl = "http://api.lmiforall.org.uk/api/v1/ashe/estimatePay?soc=";
var apicall = apiurl + socCode;
$.get(apicall, function(data) {
$("#Pay tbody").html("");
$.each(data.years, function(i, e) {
var tablerow = $("<tr></tr>");
tablerow.append("<td>" + e.year + "</td>");
tablerow.append("<td>" + e.estpay + "</td>");
$("#Pay tbody").append(tablerow);
});
});
}
and this is the table I am putting it into:
<div class="well table table-stripped">
<h4>Pay Information</h4>
<h5>Pounds per Week</h5>
<table id="Pay">
<thead>
<tr>
<th>Year</th>
<th>Estimate Pay</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
I expected it to return a year and data value into the table. if you take the url in the function and add a certain 4 figure value (the socCode) (e.g. 5113) to the end it will give the data online this should then be returned to the table body.

Have you debugged/examined the data structure inside your $.get callback? It looks to me that your access method is incorrect. When I access your example url, I get the following data back:
{
"soc":5113,
"series":[
{
"year":2012,
"estpay":340
}
]
}
I think you want your iterator to be this instead:
// there is no data.years
$.each(data.series, function(i, e) {
...
This should make your e param be of the form {year: 2012, estpay: 340}, which appears to be what you want to interpret it as.

Related

Dynamically add values from a csv in an html table using javascript/jquery

I have a dynamically generated CSV file from another vendor that I am puling in and need to show in a table on my site. The problem is I need to be able to manipulate the data from the CSV so it can show the corrected values in the html table. In the end I need the HTML table to just display the Products, not the Mixed Sets.
I am using jquery and the papaparse library to get the data and parse it in a table in html. My codepen is here:
https://codepen.io/BIGREDBOOTS/pen/YQojww
The javascript pulls the initial csv values and display in a table, but I can't figure out how to to add together the values. If there is a better way of going about this, like converting the CSV to some other form of data like JSON, That is fine too.
My CSV looks like this:
product_title,product_sku,net_quantity
Product 1,PRD1,10
Product 2,PRD2,20
Product 3,PRD3,30
Mixed Set 1,MIX1,100
Mixed Set 2,MIX2,50
Mixed Set 3,MIX3,75
The Javascript I am using is:
function arrayToTable(tableData) {
var table = $('<table></table>');
$(tableData).each(function (i, rowData) {
var row = $('<tr class="rownum-' + [i] + '"></tr>');
$(rowData).each(function (j, cellData) {
row.append($('<td class="' + [i] + '">'+cellData+'</td>'));
});
table.append(row);
});
return table;
}
$.ajax({
type: "GET",
url: "https://cdn.shopify.com/s/files/1/0453/8489/t/26/assets/sample.csv",
success: function (data) {
$('body').append(arrayToTable(Papa.parse(data).data));
}
});
My rules for the mixed set:
Mixed Set 1 should add 100 to Product 1 and Product 2.
Mixed Set 2 should add 50 to Product 2 and Product 3.
Mixed Set 3 should add 75 to Product 1, Product 2 and Product 3.
I'd like to end up with Just the products output, and the correct numbers added to the formula.
The end result would be a table with Product 1 = 185, Product 2 = 245, and Product 3 = 155.
While it would be even better if the top THEAD elements were in a "th", It's fine if that is too complicated.
<table>
<tbody>
<tr class="rownum-0">
<td class="0">product_title</td>
<td class="0">product_sku</td>
<td class="0">net_quantity</td>
</tr>
<tr class="rownum-1">
<td class="1">Product 1</td>
<td class="1">PRD1</td>
<td class="1">185</td>
</tr>
<tr class="rownum-2">
<td class="2">Product 2</td>
<td class="2">PRD2</td>
<td class="2">245</td>
</tr>
<tr class="rownum-3">
<td class="3">Product 3</td>
<td class="3">PRD3</td>
<td class="3">155</td>
</tr>
</tbody>
</table>
Without knowing the size of the dataset you're working with, I suggest you first iterate through all the CSV dataset in order to populate a list of products with the correct values, and then iterate again on that to populate your HTML table:
function datasetToMap(data) {
var ret = {};
//Initialize a map with all the product rows
$(data).each(function(index, row) {
if(row[0].startsWith("Product")) {
ret[row[1]] = row; //Using the SKU as the key to the map
}
});
//Apply your mixed sets rules to the elements in the ret array
$(data).each(function(index, row) {
if(row[1] === "MIX1") {
ret["PRD1"][2] += 100;
ret["PRD2"][2] += 100;
}
//Do the same for Mixed sets 2 and 3
});
return ret;
}
function appendMapToTable(map) {
var $table = $('#my-table');
Object.keys(map).forEach(function(key, i) {
var rowData = map[key];
var row = $('<tr class="rownum-' + [i] + '"></tr>');
$(rowData).each(function (j, cellData) {
row.append($('<td class="' + [j] + '">'+cellData+'</td>'));
});
$table.append(row);
});
}
$.ajax({
type: "GET",
url: "https://cdn.shopify.com/s/files/1/0453/8489/t/26/assets/sample.csv",
success: function (data) {
appendMapToTable(datasetToMap(Papa.parse(data).data));
}
});
Note that this expects a table with id my-table to be already present in your HTML: you could manually parse the first row of your CSV data to add the table headings.
Also note that if your CSV dataset is very big this is definitely not an optimal solution, since it requires iterating through all its lines twice and then iterating again through all the list built with computed values.

How I can order data pre date

I would like to know how I can do order data from API pre-date very time.
How its should be:
<table>
<tr>
<th>2017-02-17</th>
</tr>
<tr>
<td>some date</td>
<td>some date</td>
<td>some date</td>
</tr>
<tr>
<th>2017-02-15</th>
</tr>
<tr>
<td>some date</td>
<td>some date</td>
<td>some date</td>
</tr>
</table>
example:
URL API: http://api.tradingeconomics.com/calendar?c=guest:guest
My code:
$.ajax({
url: "url",
type: "Get",
datatype: "JSON",
contentType: "application/json",
error : function (data) { console.log("error:" + data) },
success: function (response) {
response.forEach(function (data) {
$('.top_table').append(
"<tr>" +
"<th>DATE</th>" +
"</tr>" +
"<tr id='content'>" +
"<td>some text....</td>" +
"<td>some text....</td>" +
"<td>some text....</td>" +
"<td>some text....</td>" +
"</tr>"
);
});
console.log(response);
}
});
But its print like:
date
result
date
result
How I can do it?
I don't know if I've understood your question very well, but I think that could give you some tips.
Your API returns an Array of Objects if you make and Ajax GET request, so you can order this Array before inserting the content into the DOM:
The next example order the data in descending order comparing the Date parameter, there is another date parameter called LastUpdate, I don't know if you want to use it in your logic.
$.get("https://api.tradingeconomics.com/calendar?c=guest:guest", function (data) {
//---Order the array received from the server
data.sort(function (a, b) {
return (new Date(a.Date)) - (new Date(b.Date));
});
//---The data is ordered, you can insert it into the DOM
});
In the other hand, your code inserts a row with the header content and a row with the body content in each iteration, this is not correct. You need to add all the header texts in a single row and each item of the Array needs to be inserted in separated rows.
Here you have a working example to give you an idea of the process:
https://jsfiddle.net/elchininet/ym8qp415/
EDIT: Seeing your comments, I understand now that you want to grouping the data not just ordering it. I recommend you to use the reduce method of the Array class to create a new data separated by dates and after that you can insert the data in the table:
var regdate = /^(\d{4}\-\d{2}\-\d{2})T(\d{2}:\d{2}:\d{2})$/;
//---Sort the data from the server
data.sort(function (a, b) {
return (new Date(a.Date)) - (new Date(b.Date));
});
var group = data.reduce(function (before, current) {
var day = current.Date.replace(regdate, "$1");
var hour = current.Date.replace(regdate, "$2");
if (!before[day]) {
before[day] = [];
}
current.Hour = hour;
before[day].push(current);
return before;
}, {});
//---The data is ordered and grouped, you can insert it into the DOM
Working example with fake data (Because of the example in the API returns only one day):
http://jsfiddle.net/elchininet/nvv4fnon/
Without a plugin, this is going to be difficult to achieve unless the "calendar" information is pulled from a database, it may be worth sorting in PHP, loading and displaying the data in jQuery
<script type="javascript">
$(function() {
$("BODY").on("click", "TH[data-orderby]", function() {
var order = $(this).data("orderby") || "date";
var parent = $(this).parents("table").parent();
$.ajax({
url: 'calendar?c=guest:guest',
data: 'order-by=' + URLEncode(order),
type: 'POST',
success: function(response) {
parent.html(response);
},
error: function(event, request, settings) {
console.warn("Ajax Error", request);
}
})
});
});
</script>
<div class="parent">
<table>
<thead>
<tr>
<th>Heading</th>
<th data-orderby="date">Date</th>
<th>Title</th>
<th data-orderby="last_updated">Last Updated</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
</tbody>
</table>
Because we use $("BODY").on("click", "TH[data-orderby]"), even when the data is reloaded from the server, the sort functionality will remain.
I hope this helps.

populating a bootstrap html table via jquery data

i just buil a data APIT trough Kimono -> https://www.kimonolabs.com/api/2ewmh21u?apikey=lvafgzGqR6fOqrI0mXAbiPEmQGh7rR4m.
i would like to include it in a simple and nice bootstrap table, like this: http://wenzhixin.net.cn/p/bootstrap-table/docs/examples.html.
i just tried to insert the jquery code given by kimono
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
function kimonoCallback(data) {
// do something with the data
// please make sure the scope of this function is global
}
$.ajax({
"url":"https://www.kimonolabs.com/api/2ewmh21u?apikey=lvafgzGqR6fOqrI0mXAbiPEmQGh7rR4m&callback=kimonoCallback",
"crossDomain":true,
"dataType":"jsonp"
});
</script>
but i didn't manage to create the table.
any advice?
you can active bootstrap table via javascript:
<table id="table">
<thead>
<tr>
<th data-field="nome" data-formatter="linkFormatter">Nome</th>
<th data-field="descrizione" data-formatter="linkFormatter">Descrizione</th>
</tr>
</thead>
</table>
<script>
function linkFormatter(value) {
return '' + value.text + '';
}
function kimonoCallback(data) {
$('#table').bootstrapTable({
data: data.results.collection1
});
}
$.ajax({
"url":"https://www.kimonolabs.com/api/2ewmh21u?apikey=lvafgzGqR6fOqrI0mXAbiPEmQGh7rR4m&callback=kimonoCallback",
"crossDomain":true,
"dataType":"jsonp"
});
</script>
jsFiddle: http://jsfiddle.net/wenyi/8svjf80g/33/
I have no idea what you want to display from your JSONP feed, but generally you can handle the display like so:
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Href</th>
<th>Text</th>
</tr>
</thead>
<tbody id="loadHere">
</tbody>
</table>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
function kimonoCallback(data) {
// this will help you see data structure while you develop the table
console.log(data);
// then create your table
var results = data.results.collection1,
i;
for (i = 0; i < results.length; i += 1) {
$('#loadHere').append(
'<tr>' +
'<td>' + results[i].nome.href + '</td>' +
'<td>' + results[i].nome.text + '</td>' +
'<td>' +
'</table>');
}
}
$.ajax({
"url":"https://www.kimonolabs.com/api/2ewmh21u?apikey=lvafgzGqR6fOqrI0mXAbiPEmQGh7rR4m&callback=kimonoCallback",
"crossDomain":true,
"dataType":"jsonp"
});
</script>
Be sure to look at the console to see how the data is structured so you can determine which fields to populate the table with.
Well.. You need to actually make the table when kimonoCallback gets called.
See?
// do something with the data
// please make sure the scope of this function is global

How to update tablesorter onclick in dynamic table?

I'm trying to use tablesorter on a dynamic HTML table. When the data in the table changes, and I try to sort, the table messes up; it adds the previous data and the current data and combines them both into one table, and it is also sorting other tables!! How can I make it so when the table changes, tablesorter will update? I'm populating the table from a .csv using jQuery, and the table is dynamic, because the HTML page the table is in has multiple file names, if you click on one, the data from that file will be loaded to that table
I'm using multiple tables, and one tablesorter, but here's one of my tables:
<div id="origtable">
<table border="1" id="table_side">
<thead>
<tr>
<th>Origin <br> Country</th>
<th>Count</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
Here's my tablesorter:
/* tried this at first because I'm waiting for data from .csv file to populate table
setInterval(function(){sortStuff()},1000);
function sortStuff(){
$("table").tablesorter({
sortList: [[1,1]]
});
$("table").trigger("update");
}
*/
$(document).ready(function(){
$("table").tablesorter({
sortList: [[0,1]]
});
});
$("table").on( "click", function() {
$("table").trigger("update");
});
EDIT 1:
jquery function used to populate html table after reading from .csv (this jquery code is in a seperate .js file)
function populateTableCounts(rowkey, tablename, hashdata)
{
var rowhtml = "";
$.each(hashdata, function (key, value) {
key = key.replace(/-/g, ' / ');
key = key.replace(/:/g, ' , ');
var rowdata=countrow.replace('$row_key', key);
rowdata=rowdata.replace('$row_val', value);
//add row <tr> to var rowhtml
rowhtml += rowdata;
});
//append populated rowhtml to TBODY
$('#' + tablename + ' tbody').append(rowhtml);
}
Ignore my comment is trigger("update") the function you need, but check if this code works
$(document).ready(function(){
$("table").tablesorter({
sortList: [[0,1]]
});
$("table").click(function(){ $("table").trigger("update"); });
});
EDIT
If you are using get to obtain csv data you need something like this:
$.get("your/csv/file.csv",function(csv){
//... code that handle your csv and put into table
//...
//AT END UPDATE TABLE
$("table").trigger("update");
});
EDIT2
function populateTableCounts(rowkey, tablename, hashdata)
{
var rowhtml = "";
$.each(hashdata, function (key, value) {
key = key.replace(/-/g, ' / ');
key = key.replace(/:/g, ' , ');
var rowdata=countrow.replace('$row_key', key);
rowdata=rowdata.replace('$row_val', value);
//add row <tr> to var rowhtml
rowhtml += rowdata;
});
//append populated rowhtml to TBODY
$('#' + tablename + ' tbody').append(rowhtml);
//You can do this
$('#' + tablename).trigger("update");
//or this if you want $('table').trigger('update');
}
You can do this things without problem, you need to take care that the elements must be loaded so execute all on $(document).ready.
There is no problem if the js script is on another file.

Knockout observableArray is not binding correctly

I am in the process of learning about knockout/json/mvc et al and have tried to put together an example project, but for some reason I am unable to get the data to bind correctly.
In the code snippet below, I get some JSON data from a web server and then try to map it to a function and then eventually to my knockout observableArray. What I then do is use this observableArray to bind to a HTML table. However the HTML table is not displaying any data. I put a label on to the HTML page and this does print out but with a toString() value of :
[Object object]
five times, which matches the amount of properties in the JSON data.
Can anyone see anything obvious I am missing?
JSON received from web server:
{ "Id": 1, "Name": "Inst123", "Price": 10, "DateTime": "2014-01-16T17:22:43.6383507+00:00", "Description": "Descriptions" };
.
ViewModel
$(document).ready(function () {
var gtViewModel = new GvTradeViewModel();
ko.applyBindings(gtViewModel);
console.log("ViewModel created");
});
var GvTradeViewModel = function () {
var self = this;
self.gvTrades = ko.observableArray([]);
var apiUrl = "http://localhost:57858/api/Trade/1";
console.log("Starting JSON data retrieval from: " + apiUrl);
$.getJSON(apiUrl)
// Handle success event.
.done(function (jsonData) {
if (jsonData.isEmptyObject)
console.log("NoData recieved");
else {
console.log("JSON data: " + jsonData);
var mappedTrades = $.map(jsonData, function (gvTradeData) {
return new GvTrade(gvTradeData);
});
self.gvTrades(mappedTrades);
console.log(self.gvTrades);
}
})
// Handle error/fail event.
.fail(function (jqxhr, textStatus, error) {
var err = textStatus + ", " + error;
console.log("Request Failed: " + err);
});
};
function GvTrade(data) {
this.TradeId = ko.observable(data.TradeId);
this.InstrumentName = ko.observable(data.InstrumentName);
this.DateTime = ko.observable(data.DateTime);
this.Price = ko.observable(data.Price);
this.Description = ko.observable(data.Description);
}
HTML
<table>
<thead>
<tr>
<th>TradeId</th>
<th>InstrumentName</th>
<th>Price</th>
<th>DateTime</th>
<th>Description</th>
</tr>
</thead>
<tbody data-bind="foreach: $data.gvTrades">
<tr>
<td data-bind="text: InstrumentName"></td>
<td data-bind="text: Price"></td>
<td data-bind="text: DateTime"></td>
<td data-bind="text: Description"></td>
</tr>
</tbody>
The JSON coming from your server represents a single object and not an array.
So when you are calling $.map then it does not correctly maps your data as an array, so you will end up some unusable objects.
To fix this you need to make sure that your jsonData containing an array before the map operation, you can do this with calling jQuery.makeArray on it (or you can have an if which is based on your data type decide whether you need to map or not):
var mappedTrades = $.map($.makeArray(jsonData), function (gvTradeData) {
return new GvTrade(gvTradeData);
});
Demo JSFiddle.

Categories