Javascript ES6 array loop that populates code only when on certain pages - javascript

i'm in school currently learning how to program using javascript (forgive me if my terminology is bad. feel free to correct me.) Myself and a team of four are creating a site. the requirements are that we must have 4 pages and each page needs to have a loop of some kind, we must use bootstrap, and we can only use one js file for all the pages. We are using a printToDom function to populate bootstrap cards on separate pages, and for some reason i can't get mine to work. i'm wondering if this has something to do with how our code is set up, specifically the for loops we're using. is there a way that i can incorporate an if statement that makes it to where our printToDom will print certain pieces of the for loop when on different pages? If so is there a term for it or something i can look up to get more insight?
EDIT: I probably should have said this in my original post, but I'm considering merging the two for loops that are seen in my code below because currently i have 2 separate for loops, but only one gets populated when on the tours page, the other one is supposed to populate some recent events from the array recentEvents but it doesn't. I tested it in JS fiddle and the code works there so i'm just wondering why it won't work when in the js file along side the rest of the code and I'm not sure how to phrase what i'm looking for.
javascript below for more context
const tourStops=[
{ location: "Denver, Colorado ",
venue: " Pepsi Center ",
date: "MON 04/20/2020",
id: 1
},
{
location: "Las Vegas, Nevada",
venue: " Flamingo Hotel",
date: "FRI 04/24/2020",
id: 2
},
{
location: "Hollywood, California",
venue: " Troubadour ",
date: "SAT 05/02/2020",
id: 3
},
{
location: "Portland,Oregon",
venue: " Moda Center ",
date: "FRI 05/15/2020",
id: 4
},
{
location: "Washington, D.C. ",
venue: " Capital One Arena",
date: "FRI 05/22/2020",
id: 5
},
{
location: "Bangor, Maine ",
venue: " Darlings Waterfront",
date: "FRI 06/05/2020",
id: 6
},
{
location: "Boston, Massachusetts",
venue: " Wilbur Theater ",
date: "SAT 06/20/2020",
id: 7
},
{
location: "Anchorage, Alaska ",
venue: "Atwood Concert Hall",
date: "THU 07/09/2020",
id: 8
}
];
const printToDom =(divId,textToPrint)=>{
const selectedDiv= document.getElementById(divId);
selectedDiv.innerHTML= textToPrint;
};
const buildTourDates=()=>{
let domString='';
for(let i = 0; i <tourStops.length;i++){
domString += '<div class="container px-lg-5">';
domString += '<div class="row mx-lg-n5">';
domString += `<div class="col py-3 px-lg-5 border">${tourStops[i].date}</div>`;
domString += `<div class="col py-3 px-lg-5 border">${tourStops[i].location}</div>`;
domString += `<div class="col py-3 px-lg-5 border">${tourStops[i].venue}</div>`;
domString += `<a class="btn btn-success border" href="https://www.ticketnetwork.com/en/concerts" role="button" id= "tickets" onclick= "btnPurchase(${tourStops[i].id})" class="btn btn-success border">Purchase Tickets</a>`;
domString += '</div>';
domString += '</div>';
}
printToDom('tourdates',domString)
};
const btnPurchase= (id)=>{
for(let i=0; i < tourStops.length; i++){
if(tourStops[i].id === id) {
return;
}
}
};
const eventsForTickets = () => {
document.getElementById("tickets").addEventListener('click', btnPurchase);
};
const recentEvents = [
{
event: "New Tour!",
para: "text to be inserted into this event. Lorum ipsum to see how more text looks.",
img: ""
},
{
event: "New Album",
para: "text to be inserted into this event. Lorum ipsum to see how more text looks.",
img: ""
},
{
event: "Something",
para: "text to be inserted into this event. Lorum ipsum to see how more text looks.",
img: ""
},
];
const buildEvents = () => {
let domString='';
for(let i = 0; i < recentEvents.length; i++){
domString += `<div class="media">`;
domString += `<img src="..." class="mr-3" alt="...">`;
domString += `<div class="media-body">`;
domString += ` <h5 class="mt-0">${recentEvents[i].event}</h5>`;
domString += `${recentEvents[i].para}`;
domString += `</div>`;
domString += `</div>`;
}
printToDom('newEvents',domString)
};
const initTour=()=> {
buildTourDates(tourStops);
eventsForTickets();
};
const initIndex=()=>{
buildEvents(recentEvents);
}
initTour();
initIndex();

You can use the method window.location.pathname that get the name of the specific page in which you are, according to it then you can do something like that
const pageRoute = window.location.pathname
if(pageRoute == "page-one"){
buildTourDates()
} else if(pageRoute == "page-two"){
buildEvents()
}//so on...

Related

How to show images based upon which button is selected

I have created 4 buttons in my HTML file.
I have an object in my JavaScript file named products created using curly brackets {}.
Within this object, I have an Array named data created using square brackets [].
Within this Array, I have a number of different objects created using curly brackets {}.
Each of the objects within the Array are displayed correctly. I now want to create a filter, which will only show certain objects within the Array, depending on which button is pressed.
In my HTML file, I have this code:
<div id="buttons">
<button id="all" class="button-value" onclick="filterProduct('all')">All</button>
<button id="product1" class="button-value" onclick="filterProduct('product1')">Product 1</button>
<button id="product2" class="button-value" onclick="filterProduct('product2')">Product 2</button>
<button id="product3" class="button-value" onclick="filterProduct('product3')">product3</button>
</div>
In my CSS file, I have this code:
.hide {
display: none;
}
The object I have created in JavaScript:
let products = {
data: [
{
productName: "Item 1",
category: "product1",
price: "30",
image: "image-of-the-product-1.jpg",
},
{
productName: "Item 2",
category: "product2",
price: "49",
image: "image-of-the-product-2.jpg",
},
{
productName: "Item 3",
category: "product3",
price: "99",
image: "image-of-the-product-3.jpg",
},
]
}
The filterProduct function in JavaScript:
// Parameter passed from button (Parameter same as category)
function filterProduct(value) {
// Select all elements
let elements = document.querySelectorAll(".card");
// Loop through the elements
elements.forEach((element) => {
// Display all cards on all button click
if (value == "all") {
element.classList.remove("hide");
} else {
// Check if element contains category class
if (element.classList.contains(value)) {
// Display elements based on category
element.classList.remove("hide");
} else {
// Hide other elements
element.classList.add("hide");
}
}
});
}
If the user clicks on the button with the product1 filter, only products with the category of product1 should show up. If the user clicks on a button with the product2 filter, only products with the category of product2 should show up. If the user clicks on the button with the product3 filter, only products with the category of product3 should show up. If the user clicks on the All button, all the products should be shown.
Here you can find Working demo
DEMO
I have added my own card as of now but you can change this acording your necessity.
let products = {
data: [{
productName: "Item 1",
category: "product1",
price: "30",
image: "https://via.placeholder.com/200x200",
},
{
productName: "Item 2",
category: "product2",
price: "49",
image: "https://via.placeholder.com/400x400",
},
{
productName: "Item 3",
category: "product3",
price: "99",
image: "https://via.placeholder.com/350x150",
},
{
productName: "Item 3",
category: "all",
price: "99",
image: "https://via.placeholder.com/200x100",
},
]
}
function filterAllProduct(value) {
console.clear();
let a = [];
var container = document.getElementById("displayImage");
let list = container.classList;
list.add("uicomponent-panel-controls-container");
for (var i = 0; i < products.data.length; i++) {
container.innerHTML += '<img src=' + products.data[i]['image'] + ' />';
}
}
function filterProduct(value) {
console.clear();
var newArray = products.data.filter(function(item) {
return item.category == value;
})[0];
var html = [
'<div class="uicomponent-panel-controls-container">',
'<img src=' + newArray.image + '>',
'</div>'
].join('\n');
document.getElementById("displayImage").innerHTML = html;
}
.hide {
display: none;
}
<div id="buttons">
<button id="all" class="button-value" onclick="filterAllProduct('all')">All</button>
<button id="product1" class="button-value" onclick="filterProduct('product1')">Product 1</button>
<button id="product2" class="button-value" onclick="filterProduct('product2')">Product 2</button>
<button id="product3" class="button-value" onclick="filterProduct('product3')">product3</button>
</div>
<div id="displayImage"></div>
let products = {
data: [{
productName: "Item 1",
category: "product1",
price: "30",
image: "https://via.placeholder.com/200x200",
},
{
productName: "Item 2",
category: "product2",
price: "49",
image: "https://via.placeholder.com/200x100",
},
{
productName: "Item 3",
category: "product3",
price: "99",
image: "https://via.placeholder.com/200x100",
},
{
productName: "All",
category: "all",
price: "100",
image: "https://via.placeholder.com/400x400",
},
]
}
var getSelectedValue = '';
var html = '';
function filterProduct(value) {
getSelectedValue = value;
var image1 = '';
switch (value) {
case 'all':
image1 = 'https://via.placeholder.com/200x100';
html = [
'<div class="uicomponent-panel-controls-container">',
'<img src=' + products.data[0]['image'] + '> <span>' + products.data[0]['price'] + '</span> \n',
'<img src=' + products.data[1]['image'] + '> <span>' + products.data[1]['price'] + '</span> \n',
'<img src=' + products.data[2]['image'] + '> <span>' + products.data[2]['price'] + '</span> \n',
'</div>'
].join('\n');
break;
case 'product1':
image1 = 'https://via.placeholder.com/200x200';
html = [
'<div class="uicomponent-panel-controls-container">',
'<img src=' + image1 + '> ',
'</div>'
].join('\n');
break;
case 'product2':
image1 = 'https://via.placeholder.com/400x400';
html = [
'<div class="uicomponent-panel-controls-container">',
'<img src=' + image1 + '>',
'</div>'
].join('\n');
break;
case 'product3':
image1 = 'https://via.placeholder.com/350x150';
html = [
'<div class="uicomponent-panel-controls-container">',
'<img src=' + image1 + '>',
'</div>'
].join('\n');
break;
default:
// default code block
}
if (getSelectedValue == 'all') {
}
document.getElementById("displayImage").innerHTML = html;
}
.hide {
display: none;
}
<div id="buttons">
<button id="all" class="button-value" onclick="filterProduct('all')">All</button>
<button id="product1" class="button-value" onclick="filterProduct('product1')">Product 1</button>
<button id="product2" class="button-value" onclick="filterProduct('product2')">Product 2</button>
<button id="product3" class="button-value" onclick="filterProduct('product3')">product3</button>
</div>
<div id="displayImage"></div>
If Data is static then you can use switch case this is how you can display image according button click
If Data is dynamic and you are not able to map that you can use filter to map that data

How to populate multiple JavaScript arrays of objects to HTMLDOM

I am having difficulty to get all the array of objects and display it into HTML lists. Can anyone help me, please. The below is my HTML and JavaScript code. Looking forward to your help.
const allData = [{
date: '2nd',
venue: 'venue1',
location: 'location1',
},
{
date: '3rd',
venue: 'venue2',
location: 'location2',
},
{
date: '4th',
venue: 'venue3',
location: 'location3',
}
]
allData.forEach(data => {
[...document.querySelectorAll('.targets')].forEach(list => {
list.innerHTML = `
<h5 >DATE</h5>
<h4 >${data.date}</h4>
<h5 >VENUE</h5>
<h4 >${data.venue}</h4>
<h5 >LOCATION</h5>
<h4 >${data.location}</h4>
<Button >BUY TICKETS</Button>
`;
})
});
<ul>
<li class="targets"></li>
</ul>
If you change the order of for loops execution and append each string to the previous it works!
const allData = [{
date: '2nd',
venue: 'venue1',
location: 'location1',
},
{
date: '3rd',
venue: 'venue2',
location: 'location2',
},
{
date: '4th',
venue: 'venue3',
location: 'location3',
},
];
const list = document.querySelector('.target')
let innerHTML = '';
allData.forEach(data => {
innerHTML += `
<li>
<h5 class = "shows__date">DATE</h5>
<h4 class = "shows__calander">${data.date}</h4>
<h5 class = "shows__venue-title">VENUE</h5>
<h4 class = "shows__venue">${data.venue}</h4>
<h5 class = "shows__location-title">LOCATION</h5>
<h4 class = "shows__location">${data.location}</h4>
<Button Class = "shows__btn">BUY TICKETS</Button>
</li>
`;
});
list.innerHTML = innerHTML;
<ul class="target">
</ul>
I think you don't need to loop for class='targets' because you only have one li in your html code. It might be better to just get the ul element and then loop allData variable, then change the ul innerHTML on each loop.
HTML Code
<ul></ul>
JS Code:
const allData= [
{
date: '2nd',
venue: 'venue1',
location: 'location1',
},
{
date: '3rd',
venue: 'venue2',
location: 'location2',
},
{
date: '4th',
venue: 'venue3',
location: 'location3',
},
]
let ul = document.querySelector('ul')
let listContent = ''
allData.forEach(data=>{
listContent = listContent +
`
<li>
<h5 >DATE</h5>
<h4 >${data.date}</h4>
<h5 >VENUE</h5>
<h4 >${data.venue}</h4>
<h5 >LOCATION</h5>
<h4 >${data.location}</h4>
<Button >BUY TICKETS</Button>
</li>
`;
});
ul.innerHTML = listContent
Edited based on pilchard comment
The OP provides a basic list structure by the "naked" <ul/> / <li/>
markup.
Thus, there is only a sole <li class="targets"></li> element which can be accessed with a query like '.targets'. Which means, the OP always writes to one and the same element which shows the expected result of a list which features just one element with the data-array's last item-data.
But the <li/> element can be used as a blueprint for creating other list-item elements via <node>.cloneNode which all will be <li class="targets"></li>-alike.
Now one can assign the correct data-item related html content to each newly created list-item clone which also gets appended to its parent list-element ...
const allData = [{
date: '2nd',
venue: 'venue1',
location: 'location1',
}, {
date: '3rd',
venue: 'venue2',
location: 'location2',
}, {
date: '4th',
venue: 'venue3',
location: 'location3',
}];
const venueItemBlueprint = document.querySelector('li.targets');
const venueList = venueItemBlueprint && venueItemBlueprint.parentElement;
if (venueList) {
venueList.innerHTML = '';
allData.forEach(venueData => {
const venueItem = venueItemBlueprint.cloneNode();
venueItem.innerHTML = `
<h5>DATE</h5>
<h4>${ venueData.date }</h4>
<h5>VENUE</h5>
<h4>${ venueData.venue }</h4>
<h5>LOCATION</h5>
<h4>${ venueData.location }</h4>
<Button>BUY TICKETS</Button>`;
venueList.appendChild(venueItem);
});
}
<ul>
<li class="targets"></li>
</ul>

Javascript iterating nested loops and returning specific values

I am very new to Javascript and trying to print out a selected teams NFL schedule. I have created and populated a drop down menu with all the teams. I want the user to be able to select their team and see their schedule. I am able to return the whole list (every game), but I cannot figure out how to only return the games of the selected team. Here is what the data looks like that I am using.
"Schedule": [
{
"gameId": "1",
"gameWeek": "1",
"gameDate": "2018-09-06",
"awayTeam": "ATL",
"homeTeam": "PHI",
"gameTimeET": "8:20 PM",
"tvStation": "NBC",
"winner": "PHI"
},
{
"gameId": "2",
"gameWeek": "1",
"gameDate": "2018-09-09",
"awayTeam": "BUF",
"homeTeam": "BAL",
"gameTimeET": "1:00 PM",
"tvStation": "CBS",
"winner": "BAL"
Here is the code that returned my all the games.
function processData(data){
schedule = data["Schedule"];
for(eachGame in schedule){
var game = schedule[eachGame];
var week = game["gameWeek"];
var homeTeam = game["homeTeam"];
var awayTeam = game["awayTeam"];
var winner = game["winner"];
var tableRow = "<tr><td>" + week + "</td><td>" + homeTeam + "</td><td>" + awayTeam + "</td><td>" + winner + "</td></tr>";
$("#output").append(tableRow);
}
}
I need to return when the awayTeam or homeTeam are the team that the user selected.
Thanks!
To reduce an array down to only a handful of its items, I'd almost always suggest using Array.filter(), however I'm actually going to present an alternative solution first in your case.
If you were to use filter to loop through the items and find the ones you want, and then use a for loop to append them to the table, you'd be looping through some of the same elements twice.
Instead, we can apply our logic to skip the games we don't want inside the same loop, by doing something like this:
//If "team" is neither the away team, nor the home team, skip this game
if (![game.awayTeam, game.homeTeam].includes(team)) return;
Example 1: (Comments added)
var data = { Schedule: [{ awayTeam: "Jets", homeTeam: "Bills", winner: "Bills", week: 1 }, { awayTeam: "Saints", homeTeam: "Cardinals", winner: "Cardinals", week: 1 }, { awayTeam: "Giants", homeTeam: "Bengals", winner: "Bengals", week: 2 }, { awayTeam: "Bills", homeTeam: "Jaguars", winner: "Bills", week: 2 }, { awayTeam: "Bills", homeTeam: "Patriots", winner: "Patriots", week: 3 } ] };
function setScheduleByTeam(team) {
let schedule = data["Schedule"]; //Get the schedule
var $outputTable = $("#output"); //Store the table as a variable
$outputTable.find("tbody").empty(); //Empty out the current records
schedule.forEach(function(game) { //For each game in the schedule
if (![game.awayTeam, game.homeTeam].includes(team)) return; //Skip the record if our team isn't in it
//Create + Append table row
var tableRow = "<tr><td>" + game.week + "</td><td>" + game.homeTeam + "</td><td>" + game.awayTeam + "</td><td>" + game.winner + "</td></tr>";
$outputTable.append(tableRow);
});
}
//On button click
$("body").on("click", "button", function() {
let team = $('#teamSelect').val(); //Get selected team
setScheduleByTeam(team); //Update the table to that team's schedule
});
td,th { padding: 5px 15px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="teamSelect">
<option>Select Team</option>
<option value="Bengals">Bengals</option>
<option value="Bills">Bills</option>
<option value="Jets">Jets</option>
</select>
<button>Go!</button>
<table id="output">
<thead>
<tr>
<th>Week</th>
<th>Home</th>
<th>Away</th>
<th>Winner</th>
</tr>
</thead>
</table>
However, some might argue for cleanliness, in which case I'd suggest going with the filter method I mentioned earlier:
Example 2 (Comments added)
var data = { Schedule: [{ awayTeam: "Jets", homeTeam: "Bills", winner: "Bills", week: 1 }, { awayTeam: "Saints", homeTeam: "Cardinals", winner: "Cardinals", week: 1 }, { awayTeam: "Giants", homeTeam: "Bengals", winner: "Bengals", week: 2 }, { awayTeam: "Bills", homeTeam: "Jaguars", winner: "Bills", week: 2 }, { awayTeam: "Bills", homeTeam: "Patriots", winner: "Patriots", week: 3 } ] };
//Filter out schedule to only games where awayTeam == team OR homeTeam == team.
//Returns the filtered team's schedule
const getGamesByTeam = (team) => data.Schedule.filter(g => g.awayTeam == team || g.homeTeam == team);
function updateScheduleTable(games) {
var $outputTable = $("#output"); //Store table as variable
$outputTable.find("tbody").empty(); //Remove existing rows
games.forEach(function(game) { //For each game, append to table
var tableRow = "<tr><td>" + game.week + "</td><td>" + game.homeTeam + "</td><td>" + game.awayTeam + "</td><td>" + game.winner + "</td></tr>";
$outputTable.append(tableRow);
});
}
$("body").on("click", "button", function() {
let team = $('#teamSelect').val(); //Get the selected team
let games = getGamesByTeam(team); //Get a filtered array of one team's schedule
updateScheduleTable(games); //Update the table based on that set of games
});
td,th { padding: 5px 15px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="teamSelect">
<option>Select Team</option>
<option value="Bengals">Bengals</option>
<option value="Bills">Bills</option>
<option value="Jets">Jets</option>
</select>
<button>Go!</button>
<table id="output">
<thead>
<tr>
<th>Week</th>
<th>Home</th>
<th>Away</th>
<th>Winner</th>
</tr>
</thead>
</table>
You need to sort your array of data based on the user's selected team. To do that, you need to use an array method to loop over the array and return values based on logic you put in the loop. To do this, I used the reduce method (IMO the most useful array method).
function filterForSelectedTeam(data) {
const accumulator = [];
const team = $('#teamSelect').val();
const schedule = data["Schedule"];
// if team has a value this reduce method will return a sorted array
// based on the logic in the loop.
return team && schedule.reduce((acc, game) => {
if (game["homeTeam"] === team || game['awayTeam'] === team) {
acc.push(game);
};
return acc;
}, accumulator);
}
const data = [] // your data here;
const gamesBySelectedTeam = filterForSelectedTeam(data)
gamesBySelectedTeam.forEach(game => {
const tableRow = "<tr><td>" + game['gameWeek'] + "</td><td>" + game['homeTeam'] + "</td><td>" + game['awayTeam'] + "</td><td>" + game['winner'] + "</td></tr>";
$("#output").append(tableRow);
});
Here is a way to do this with just a few method calls:
function processData({ Schedule: s }, team) {
// s is now the equivolent of data['Schedule']
// Filter the data to get all games where either
// the away of home team is the team sent in
// Empty the table so it includes only those games appended below
// Append the array of games as html elements
$("#output")empty().append(
s.filter(g => g.awayTeam === team || g.homeTeam === team)
.map(g => {
`<tr>
<td>${game.gameWeek}</td>
<td>${game.homeTeam}</td>
<td>${game.awayTeam}</td>
<td>${game.winner}</td>
</tr>`
})
);
}
You can append an array of html strings to the DOM and they get handled properly.

JavaScript Deeply Nested Array filtering

I have created a somehow functional "deeply" nested array filtering functionality. This functionality displays car, which has a color "RED" assigned to them. However the cars, which "pass" the filter is the car, which only has 1 color assigned. How can ensure that arrays within arrays are being checked by the criteria? Would I require creating a loop within loop? The desired outcome would be that if criteria is set to "RED" it will also display the BMW and SUZUKI as these cars also have this color. Any help, suggestions or further links to other posts to achieve the desired outcome would be truly appreciated as I was not able to find anything very useful on my own. The post, which has been most useful has been this one - Filtering an array with a deeply nested array in JS Below I have attached the code snippet of my current code.
const myCars = [
{ name: "BMW",colour: ["White","Red","Black"] },
{ name: "AUDI",colour: ["Yellow","Silver"] },
{ name: "VW",colour: ["Purple","Gold"] },
{ name: "NISSAN",colour: ["White","Black"] },
{ name: "SUZUKI",colour: ["Red"] },
];
for (x in myCars) {
var keys = Object.keys(myCars[x])
var carSpec = myCars.filter(function(fltr) {
return (fltr.colour == "Red");
});
document.getElementById("show1").innerHTML += carSpec[x].name + " " + "has these colours - " + carSpec[x].colour + "<hr />";
}
<p>Car List.</p>
<p id="show"></p>
<p id="show1"></p>
You need to filter by an includes test over the colour array:
const myCars = [
{ name: "BMW",colour: ["White","Red","Black"] },
{ name: "AUDI",colour: ["Yellow","Silver"] },
{ name: "VW",colour: ["Purple","Gold"] },
{ name: "NISSAN",colour: ["White","Black"] },
{ name: "SUZUKI",colour: ["Red"] },
];
const show1 = document.getElementById("show1");
myCars
.filter(({ colour }) => colour.includes('Red'))
.forEach(({ name, colour }) => {
show1.innerHTML += name + " " + "has these colours - " + colour + "<hr />";
});
<p>Car List.</p>
<p id="show"></p>
<p id="show1"></p>
You can use reduce to get an array of cars which have are available in red , then use forEach to loop over it and display the text.
join will join all the contents of an array by the delimiter
const myCars = [{
name: "BMW",
colour: ["White", "Red", "Black"]
},
{
name: "AUDI",
colour: ["Yellow", "Silver"]
},
{
name: "VW",
colour: ["Purple", "Gold"]
},
{
name: "NISSAN",
colour: ["White", "Black"]
},
{
name: "SUZUKI",
colour: ["Red"]
},
];
let hasRed = myCars.reduce(function(acc, curr) {
if (curr.colour.indexOf('Red') !== -1) {
acc.push(curr)
}
return acc;
}, []).forEach((item) => {
document.getElementById("show1").innerHTML += item.name + " " + "has these colours - " + item.colour.join(',') + "<hr />";
})
<p>Car List.</p>
<p id="show"></p>
<p id="show1"></p>

javascript for loop not iterating completely through object

I'm currently experimenting with dynamically loading data from a JS Object into html containers by iterating over it with a For Loop.
The wall I have hit seems to be because the For Loop won't iterate through the whole object, even though I'm setting high threshold of the For Loop based on a calculation of the amount of objects that are held within the JS Object.
A working solution will have all objects loaded into their respective html containers. At this point I'm not fussed about showing the objects inside the achievements property object.
This experiment is to better understand Pure Javascript so no Jquery or framework suggestions please.
Data Object:
var data = { projects: [{
title: "GET BORN",
tags: ["Live Events", "Stage Design", "Event Promotion", "Music"],
date_started: "21/09/12",
date_finished: "Finish Date",
description: "Music events that explores the underground sound",
achievements: [{milestone:"Launched Brand", date:"datetime", details:"blah"}, {milestone:"Hosted First Night", date:"datetime", details:"moreblah"}, {milestone:"Sold Out Lakota +1000 People", date:"datetime", details:"moreblah"}],
position: 1
}, {
title: "FAIRSTREAM",
tags: ["Web Application", "Trademark", "Music streaming"],
date_started: "10/05/16",
date_finished: "Finish date",
description: "Equal opportunity music streaming application",
achievements: [{milestone:"Launched Brand", date:"datetime", details:"blah"}],
position: 2
}]}
View Generating Function:
const buildProjectView = (dataSet) => {
const currentProjectIndex = 0
let dataLen = Object.keys(dataSet.projects[currentProjectIndex]).length
// console.log(dataLen)
let objKey = Object.keys(dataSet.projects[currentProjectIndex])
let objValue = Object.values(dataSet.projects[currentProjectIndex])
// console.log(objValue)
for (let i = 0; i < dataLen; i++) {
// console.log("count: " + i)
console.log(objKey[i] + ": " + objValue[i])
let theTitle = document.getElementById(objKey[i])
let content = document.createTextNode(objValue[i])
theTitle.appendChild(content)
}
}
window.onload = buildProjectView(data)
HTML Boilerplate:
<html>
<head>
  <title>Mysite Playground</title>
</head>
<body>
<div class="container">
<section class="head">
<h1 id="title"/>
<h2 id="description"/>
<h3 id="date_started"/>
</section>
<section class="body">
<p id="position">#</p>
<p id="achievements"/>
<p id="tags"/>
</section>
</div>
</body>
</html>
My coding test platform with example and some basic styling:
https://codepen.io/wntwrk/pen/bqXYMO
Thanks for your help in advance.
This should give you a starting point to give you something to work with.
You have an array with arrays in it and an array of objects.
Note that simply "pushing" stuff into the DOM on the existing markup/boilerplate does not help you, you need to clone that to allow more instances - which is what I did.
Using this data provided:
/*jshint esversion: 6 */
var data = {
projects: [{
title: "GET BORN",
tags: ["Live Events", "Stage Design", "Event Promotion", "Music"],
date_started: "21/09/12",
date_finished: "Finish Date",
description: "Music events that explores the underground sound",
achievements: [{
milestone: "Launched Brand",
date: "datetime",
details: "blah"
}, {
milestone: "Hosted First Night",
date: "datetime",
details: "moreblah"
}, {
milestone: "Sold Out Lakota +1000 People",
date: "datetime",
details: "moreblah"
}],
position: 1
}, {
title: "FAIRSTREAM",
tags: ["Web Application", "Trademark", "Music streaming"],
date_started: "10/05/16",
date_finished: "Finish date",
description: "Equal opportunity music streaming application",
achievements: [{
milestone: "Launched Brand",
date: "datetime",
details: "blah"
}],
position: 2
}]
};
I added some functions to hopefully make it easier to understand.
// convert the "boilerplate" to a class based avoiding duplicate id's
function idToClass(node) {
var child, nodes = node.childNodes;
for (var i = 0, len = nodes.length; i < len; i++) {
child = nodes[i];
if (typeof child.id === 'string' && child.id !== "") {
child.className = child.id;
child.removeAttribute("id");;
}
if (child.childNodes && child.childNodes.length) {
idToClass(child);
}
}
}
let addItem = (project, aclone, name) => {
let el = aclone.getElementsByClassName(name);
if (el.length && typeof project[name] !== "object") {
el[0].textContent = project[name];
}
if (el.length && typeof project[name] === "object") {
/// do something with objects like the "achievements"
}
};
let addProject = (project, aclone) => {
var k = Object.keys(project);
k.forEach(function(item) {
addItem(project, aclone, item);
});
return aclone;
};
const buildProjectView = (dataSet) => {
let y = document.getElementsByClassName('container');
//clone and change ids to classes
let aclone = y[0].cloneNode(true);
idToClass(aclone);
for (let i = 0; i < dataSet.projects.length; i++) {
let n = addProject(dataSet.projects[i], aclone.cloneNode(true));
y[0].parentNode.appendChild(n, aclone);
}
// COULD remove the boilerplate here:
// y[0].removeNode();
};
window.onload = buildProjectView(data);

Categories

Resources