So I'm using https://calendarific.com api and am trying to make an "app" where you can click on your country and it returns the holidays based on the current month. It kinda works except when I click on one country and then another the previous countries result stays on the top and the new country's holidays get put to the bottom of the page.
How can I remove previous results when a new one is made?
Javascript (sorry if it's a bit messy):
countrySelect.addEventListener('click', function() {
// Api url
let url = `https://calendarific.com/api/v2/holidays?&api_key=a7167178ffb6d2d7d8d9c1e05d98eab926f595e9&country=${buttonValue}&year=2020`;
fetch(url)
.then(res => res.json())
.then(data => {
// Filters holiday's to the current month
var currentMonthHolidays = data.response.holidays.filter(holiday => {
var holidayDate = new Date(holiday.date.iso);
var holidayMonth = holidayDate.getMonth();
var date = new Date();
var currentMonth = date.getMonth();
return currentMonth === holidayMonth;
})
// Build holiday table
function buildTable(data){
let table = document.getElementById('resultTable');
let col = [];
// Get the index of the api titles
for (let i = 0; i < currentMonthHolidays.length; i++) {
for (let key in currentMonthHolidays[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
console.log(col)
}
//Create table header row using the extracted headers above.
let tr = table.insertRow(-1); // table row.
for (let i = 0; i < col.length; i++) {
let th = document.createElement("th"); // table header.
th.innerHTML = col[i];
tr.appendChild(th);
}
// add json data to the table as rows.
for (let i = 0; i < currentMonthHolidays.length; i++) {
tr = table.insertRow(-1);
for (let j = 0; j < col.length; j++) {
let tabCell = tr.insertCell(-1);
tabCell.innerHTML = currentMonthHolidays[i][col[j]];
}
}
}
buildTable(currentMonthHolidays);
console.log(currentMonthHolidays);
//handles error
}, networkError => {
alert(networkError)
})
})
If you are only concerned about just getting new data on top,
in your code just add :
table.removeChild(table.tBodies[0]);
which becomes :-
countrySelect.addEventListener('click', function() {
// Api url
let url = `https://calendarific.com/api/v2/holidays?&api_key=a7167178ffb6d2d7d8d9c1e05d98eab926f595e9&country=${buttonValue}&year=2020`;
fetch(url)
.then(res => res.json())
.then(data => {
// Filters holiday's to the current month
var currentMonthHolidays = data.response.holidays.filter(holiday => {
var holidayDate = new Date(holiday.date.iso);
var holidayMonth = holidayDate.getMonth();
var date = new Date();
var currentMonth = date.getMonth();
return currentMonth === holidayMonth;
})
// Build holiday table
function buildTable(data){
let table = document.getElementById('resultTable');
let col = [];
// Get the index of the api titles
for (let i = 0; i < currentMonthHolidays.length; i++) {
for (let key in currentMonthHolidays[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
console.log(col)
}
//Create table header row using the extracted headers above.
let tr = table.insertRow(-1); // table row.
for (let i = 0; i < col.length; i++) {
let th = document.createElement("th"); // table header.
th.innerHTML = col[i];
tr.appendChild(th);
}
/*
since all <tr> are wrapped inside <tbody>, so just remove the old one and you are good to go
*/
table.removeChild(table.tBodies[0]);
// add json data to the table as rows.
for (let i = 0; i < currentMonthHolidays.length; i++) {
tr = table.insertRow(-1);
for (let j = 0; j < col.length; j++) {
let tabCell = tr.insertCell(-1);
tabCell.innerHTML = currentMonthHolidays[i][col[j]];
}
}
}
buildTable(currentMonthHolidays);
console.log(currentMonthHolidays);
//handles error
}, networkError => {
alert(networkError)
})
})
Related
I'm trying to have a bunch of memes show up on my HTML page. I'm using this URL https://api.memegen.link/images. I'm having lots of trouble trying to display images. I cannot figure out how to use this link. The link has what looks like a bunch of JSON code and the actual website has very little documentation on how to use it.
Here's the Javascript code. The HTML is just 2 divs and an input that has an onClick that call the function
$(document).ready(function imagesFromJSON() {
$.getJSON("https://api.memegen.link/images", function (data) {
var arrItems = []; // The array to store JSON items.
$.each(data, function (index, value) {
arrItems.push(value); // Push values in the array.
});
// Extract values for the table header.
var col = [];
for (var i = 0; i < arrItems.length; i++) {
for (var key in arrItems[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
}
var table = document.createElement("table");
var tr = table.insertRow(-1); // Table row.
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // Table header.
th.innerHTML = col[i];
tr.appendChild(th);
}
// Add JSON data to the table as rows.
for (var i = 0; i < arrItems.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
if (j === 2) { // The last JSON column has image urls.
// Create an <img> element to show the images.
var img = document.createElement('img');
img.src = arrItems[i].Image; // The image source from JSON array.
tabCell.appendChild(img);
}
else
tabCell.innerHTML = arrItems[i][col[j]];
}
}
// Finally, add the newly created <table> with data to a container.
var divContainer = document.getElementById("showData");
divContainer.innerHTML = "";
divContainer.appendChild(table);
});
});
You can use fetch API in JavaScript directly to call the memeAPI.
For generating the table inside your JavaScript, you can use Template literals which will make it easy for you to construct the tables.
const getMemeBtn = document.querySelector("#get-meme");
getMemeBtn.addEventListener("click", getMeme);
function getMeme(){
fetch("https://api.memegen.link/images")
.then(res => res.json())
.then(data => {
let HTMLContent = `<table>
<tr>
<th>Meme Template</th>
<th>Meme Image</th>
</tr>
`;
for(let i = 0; i < 5; i++){
let memeImgURL = data[i].url;
let memeName = data[i].template;
HTMLContent += `
<tr>
<td>${memeName}</td>
<td><img width="100" height="100" src="${memeImgURL}"></td>
</tr>
`;
}
HTMLContent += `</table>`;
document.getElementById("memes").innerHTML = HTMLContent;
})
.catch(err => console.log(err));
}
<button type="button" id="get-meme">Get Meme</button>
<br><br><br><br>
<div id="memes"></div>
I am trying to add edit and delete button inside the column but the HTML table was created from JSON file and it is using for loop to print out the content. I don't know how to add extra button inside the column (green zone).
The button that plan to add will be replace in the 'undefined' col.
JSON code:
[
{
"userId":"ravjy",
"jobTitleName":"Developer",
"firstName":"Ran",
"lastName":"Vijay",
"preferredFullName":"Ran Vijay",
"employeeCode":"H9",
"region":"DL",
"phoneNumber":"34567689",
"emailAddress":"ranvijay.k.ran#gmail.com"
},
{
"userId":"mrvjy",
"jobTitleName":"Developer",
"firstName":"Murli",
"lastName":"Vijay",
"preferredFullName":"Murli Vijay",
"employeeCode":"A2","region":"MU",
"phoneNumber":"6543565",
"emailAddress":"murli#vijay.com"
}
]
<script>
fetch('employees.json')
.then(function (response) {
// The JSON data will arrive here
return response.json();
})
.then(function (data) {
appendData(data);
})
.catch(function (err) {
// If an error occured, you will catch it here
});
function appendData(data) {
//Extract Value for HTML HEADER.
var col=[];
for (var i = 0; i<data.length;i++){
for (var key in data[i]){
if (col.indexOf(key) === -1){
col.push(key);
}
}
}
//Add edit and delete header
col.push("Edit","Delete");
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
var tr = table.insertRow(-1); // TABLE ROW.
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // TABLE HEADER.
th.innerHTML = col[i];
tr.appendChild(th);
}
// ADD JSON DATA TO THE TABLE AS ROWS.
for (var i = 0; i < data.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = data[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("myData");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
</script>
[1]: https://i.stack.imgur.com/YpoDi.png
[2]: https://i.stack.imgur.com/pu7SB.png
Solution
Javascript map will help to get that working
const data = [
{
userId: "ravjy",
jobTitleName: "Developer",
firstName: "Ran",
lastName: "Vijay",
preferredFullName: "Ran Vijay",
employeeCode: "H9",
region: "DL",
phoneNumber: "34567689",
emailAddress: "ranvijay.k.ran#gmail.com",
},
{
userId: "mrvjy",
jobTitleName: "Developer",
firstName: "Murli",
lastName: "Vijay",
preferredFullName: "Murli Vijay",
employeeCode: "A2",
region: "MU",
phoneNumber: "6543565",
emailAddress: "murli#vijay.com",
},
];
function test(type, id) {
alert(type + " " + id);
}
function appendData(data) {
//Extract Value for HTML HEADER.
data = data.map((item) => {
item.Edit_Delete = `<Button type="button" onclick="test('Edit', '${item.userId}')">${item.userId}</Button>
<Button type="button" onclick="test('Delete', '${item.userId}')">${item.userId}</Button>`;
return item;
});
const col = [];
for (let i = 0; i < data.length; i++) {
for (let key in data[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
}
//Add edit and delete header
// col.push("Edit","Delete");
// CREATE DYNAMIC TABLE.
const table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
let tr = table.insertRow(-1); // TABLE ROW.
for (let i = 0; i < col.length; i++) {
const th = document.createElement("th"); // TABLE HEADER.
th.innerHTML = col[i];
tr.appendChild(th);
}
// ADD JSON DATA TO THE TABLE AS ROWS.
for (let i = 0; i < data.length; i++) {
tr = table.insertRow(-1);
for (let j = 0; j < col.length; j++) {
const tabCell = tr.insertCell(-1);
tabCell.innerHTML = data[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
const divContainer = document.getElementById("myData");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
appendData(data);
<!DOCTYPE html>
<html>
<body>
<div id ="myData"></div>
</body>
</html>
I want to create an HTML table using json data. The json data will change over time. When convert this json data to an HTML table, the table looks like this with consistent. It means the alignment of values and the width of the table. How can I convert the json data into an HTML table?
[
{
"1": [{
"Time": "01:35 AM",
"Location": "dhaka bangladesh",
"BUS Detail": {
"air_Logo": "logo goes here",
"air_Name": "Airbus"
},
"busNo": "AK119",
"arrTime": "05:40 AM",
"arrival Loc": "barisal"
}]
}
]`// Extract value from table header.
let col = [];
for (let i = 0; i < myBooks.length; i++) {
for (let key in myBooks[i]) {
if (col.indexOf(key) == -1) {
col.push(key);
}
}
}
// Create a table.
const table = document.createElement("table");
// Create table header row using the extracted headers above.
let tr = table.insertRow(-1); // table row.
for (let i = 0; i < col.length; i++) {
let th = document.createElement("th"); // table header.
th.innerHTML = col[i];
tr.appendChild(th);
}
// add json data to the table as rows.
for (let i = 0; i < myBooks.length; i++) {
tr = table.insertRow(-1);
for (let j = 0; j < col.length; j++) {
const tabcel = tr.insertCell(-1);
if (typeof myBooks[i][col[j]] === 'object') {
tabcel.setAttribute('rowspan','2');
tabcel.innerHTML = `<table><td>${myBooks[i][col[j]].air_Name}</td> <td> ${myBooks[i][col[j]].air_Logo}</td> </table>`;
} else {
tabcel.innerHTML = myBooks[i][col[j]];
}
}
// for (let j = 0; j < col.length; j++) {
// let tabCell = tr.insertCell(-1);
// tabCell.innerHTML = myBooks[i][col[j]];
// }
}
// Now, add the newly created table with json data, to a container.
const divShowData = document.getElementById('showData');
divShowData.innerHTML = "";
divShowData.appendChild(table);`
Since your object is not flat, you cannot truly render it all to table. You have to make a decision about the nested objects. Below I am simply using json.stringify to show those objects in a table cell. You should of course handle this according to your needs.
const data = [
{
"1": [
{
Time: "01:35 AM",
Location: "dhaka bangladesh",
"BUS Detail": {
air_Logo: "logo goes here",
air_Name: "Airbus"
},
busNo: "AK119",
arrTime: "05:40 AM",
"arrival Loc": "barisal"
}
]
}
];
const base = data[0]["1"];
const table = document.createElement("table");
const thead = table.createTHead();
const tbody = document.createElement("tbody");
table.append(tbody)
const headRow = thead.insertRow();
const headers = Object.keys(base[0]).forEach((head) => {
let cell = headRow.insertCell();
cell.textContent = head;
});
base.forEach((obj) => {
const row = tbody.insertRow();
const vals = Object.values(obj);
vals.forEach((v) => {
const cell = row.insertCell();
if (typeof(v) !== 'string') {
return cell.textContent = JSON.stringify(v);
}
cell.textContent = v
});
});
document.body.append(table)
I'm currently using the following code to create a table based on a JSON API. I want to change the title of the table columns to be Name and Score instead of userName and userScore...
I have tried adjusting the forEach statement that creates the table columns, but that didn't work...
axios
.get("[ip censored]/scores")
.then(function(response) {
let sortedList = response.data.sort((a, b) => b.userScore - a.userScore);
console.warn(sortedList);
// EXTRACT VALUE FOR HTML HEADER.
var col = [];
for (var i = 0; i < sortedList.length; i++) {
for (var key in sortedList[i]) {
if (
col.indexOf(key) === -1 &&
(key === "userName" || key === "userScore")
) {
col.push(key);
}
}
}
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
var tr = table.insertRow(-1); // TABLE ROW.
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // TABLE HEADER.
th.innerHTML = col[i];
tr.appendChild(th);
}
// ADD JSON DATA TO THE TABLE AS ROWS.
for (var i = 0; i < sortedList.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = sortedList[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("leaderboard");
divContainer.innerHTML = "";
divContainer.appendChild(table);
})
.catch(function(error) {
console.error(error);
});
I also tried using CSS to make the tables look prettier, but it still didn't work.
Given you know the incoming key names and that they're consistent a simple inline if/else in your JavaScript should be all you need.
Try this:
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // TABLE HEADER
// This inline if says if col[i] is userName then set innerHTML to Name, else Score
th.innerHTML = col[i]==='userName' ? 'Name' : 'Score';
tr.appendChild(th);
}
Never mind, I figured it out. I used an if statement, and if col[i] equaled the value I wanted, I changed the value before I pushed the table.
You can use an if statement.
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // TABLE HEADER.
var heading = "";
if(col[i] == "userName"){
th.innerHTML = "Name";
}
else if(col[i] == "userScore"){
th.innerHTML = "Score";
}
tr.appendChild(th);
}
I am currently using:
function searchNotes() {
const url = "http://localhost:2609/api/notes"
$.ajax({
url: url,
type: 'GET',
success: function (notesList) {
console.log(notesList)
// EXTRACT VALUE FOR HTML HEADER.
var col = [];
for (var i = 0; i < notesList.length; i++) {
for (var key in notesList[i]) {
if (col.indexOf(key) === -1 && (key === 'title' || key === 'content' || key == 'category' || key == 'categoryId')) {
col.push(key);
}
}
}
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
var tr = table.insertRow(-1); // TABLE ROW.
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // TABLE HEADER.
th.innerHTML = col[i];
tr.appendChild(th);
}
// ADD JSON DATA TO THE TABLE AS ROWS.
for (var i = 0; i < notesList.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = notesList[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("listNotes");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
});
}
to create a html table using jquery. The table looks like this:
I want to filter the table by categoryId, as chosen in the dropdown at the top, then I want to remove the categoryId column. Any ideas how I could achieve this?
You need to use .sort() on the notesList object, something like this:
notesList.sort(function(a, b) {
return a.categoryId - b.categoryId;
});
Put it before appending the values to the html.
To 'remove' the categoryId column is very simple: Just remove the followingen bit from the if statement:
|| key == 'categoryId'
So your end result is something like this:
function searchNotes() {
const url = "http://localhost:2609/api/notes"
$.ajax({
url: url,
type: 'GET',
success: function (notesList) {
notesList.sort(function(a, b) {
return a.categoryId - b.categoryId;
});
// EXTRACT VALUE FOR HTML HEADER.
var col = [];
for (var i = 0; i < notesList.length; i++) {
for (var key in notesList[i]) {
if (col.indexOf(key) === -1 && (key === 'title' || key === 'content' || key == 'category')) {
col.push(key);
}
}
}
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
var tr = table.insertRow(-1); // TABLE ROW.
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // TABLE HEADER.
th.innerHTML = col[i];
tr.appendChild(th);
}
// ADD JSON DATA TO THE TABLE AS ROWS.
for (var i = 0; i < notesList.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = notesList[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("listNotes");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
});
}