Create Firebase Blog Post with <iframe> - javascript

I have a Firebase Blog on my website. Now I want to post iframes on it.
My idea is to push them like the other p tags from JavaScript into the HTML and write the Link into the database without the frame tag...but it didnĀ“t work. Does anyone know why? Here is the Code without frame tag:
I have following JavaScript Code:
let postCollection = document.querySelector("#posts-collection");
const db = firebase.firestore();
function createPost(title, time, content) {
let div = document.createElement("div");
div.setAttribute("class", "col-md-4");
let h2 = document.createElement("h2");
let p = document.createElement("p");
let small = document.createElement("small");
h2.textContent = title;
small.textContent = time;
p.textContent = content;
div.appendChild(h2);
div.appendChild(small);
div.appendChild(p);
postCollection.appendChild(div);
}
// Get Posts
function getPosts() {
db.collection("posts")
.get()
.then(snapshot => {
snapshot.docs.forEach(docs => {
createPost(
docs.data().postName,
docs.data().createdAt,
docs.data().postContent
);
});
})
.catch(err => {
console.log(err);
});
}
getPosts();
And the following HTML for it:
<div class="blog" id="blog">
<h1>Blog</h1>
<!-- Example row of columns -->
<div class="row" id="posts-collection"></div>
</div>

Here is my idea to post iframes:
let postCollection = document.querySelector("#posts-collection");
const db = firebase.firestore();
function createPost(title, time, content, link) {
let div = document.createElement("div");
div.setAttribute("class", "col-md-4");
let h2 = document.createElement("h2");
let p = document.createElement("p");
let small = document.createElement("small");
let frame = document.createElement("iframe");
h2.textContent = title;
small.textContent = time;
p.textContent = content;
iframe.textContent = link
div.appendChild(h2);
div.appendChild(small);
div.appendChild(p);
div.appendChild(iframe)
postCollection.appendChild(div);
}
// Get Posts
function getPosts() {
db.collection("posts")
.get()
.then(snapshot => {
snapshot.docs.forEach(docs => {
createPost(
docs.data().postName,
docs.data().createdAt,
docs.data().postContent
);
});
})
.catch(err => {
console.log(err);
});
}
getPosts();

Related

Javascript and Google Sheet - Display only one element of array

I'm learning javascript, hence my question might be a bit silly/simple.
Following a tutorial on Udemy, I was able to display a spreadsheet from Google Sheet in my website, using javascript to retrieve all rows contained in the document and pass them to a container in an HTML page.
This is great.
Now I would like to visualise only one row at a time, at a specific interval.
After some search I realised I can do this by using getElementById in conjunction with .innerHTML within a loop but I can't figure out what I am supposed to pass and where.
So, here is the HTML I'm using
<!DOCTYPE html>
<html><head><title>Testing Data from Sheets</title></head>
<body>
<div class="output"></div>
<script src="sheets.js"></script>
</body>
</html>
And here is the JS
const sheetID = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
const base = `https://docs.google.com/spreadsheets/d/${sheetID}/gviz/tq?`;
const sheetName = 'quotes';
let qu = 'Select D';
const query = encodeURIComponent(qu);
const url = `${base}&sheet=${sheetName}&tq=${query}`;
const data = [];
document.addEventListener('DOMContentLoaded', init);
const output = document.querySelector('.output');
function init() {
console.log('ready');
fetch(url)
.then(res => res.text())
.then(rep => {
//console.log(rep);
const jsData = JSON.parse(rep.substr(47).slice(0, -2));
console.log(jsData);
const colz = [];
jsData.table.cols.forEach((heading) => {
if (heading.label) {
colz.push(heading.label.toLowerCase().replace(/\s/g, ''));
}
})
jsData.table.rows.forEach((main) => {
//console.log(main);
const row = {};
colz.forEach((ele, ind) => {
//console.log(ele);
row[ele] = (main.c[ind] != null) ? main.c[ind].v : '';
})
data.push(row);
})
maker(data);
})
}
function maker(json) {
const div = document.createElement('div');
div.style.display = 'grid';
output.append(div);
let first = true;
json.forEach((el) => {
//console.log(ele);
const keys = Object.keys(el);
div.style.gridTemplateColumns = `repeat (${keys.length} ,'1fr')`;
if (first) {
first = false;
keys.forEach((heading) => {
const ele = document.createElement('div');
//ele.textContent = heading.toLocaleUpperCase();
ele.style.background = 'black';
ele.style.color = 'white';
ele.style.fontFamily = 'Helvetica';
div.append(ele);
})
}
keys.forEach((key) => {
const ele = document.createElement('div');
//ele.style.border = '1px solid #ddd';
ele.textContent = el[key];
ele.style.background = 'black';
ele.style.color = 'white';
ele.style.fontFamily = 'Helvetica';
div.append(ele);
})
console.log(keys);
})
}
Thanks heaps for helping!
I tried using the following from other messages I've found on the forum:
var i = 0; // the index of the current item to show
setInterval(function() { // setInterval makes it run repeatedly
document
.getElementById('output')
.innerHTML = jsData[i++];
if (i == jsData.length) i = 0;
}, 1000);

How can I add a row to my html document for every player including their stats?

The code currently takes from a .log I have, and grabs the username of players in my lobby and returns stats (# of wins, level, etc.) of the player onto an electron HTML page in a table.
Currently, it only shows one row, with only one players' stats included in the row. I am trying to make it so that each player will show up in stacking rows.
Picture of what the html electron window shows
I also want the rows to update every time "checkforupdates" is ran but I figured I should stick to one issue at a time.
const { app, BrowserWindow } = require('electron');
const fs = require('fs');
const prompt = require('prompt-sync')();
const Hypixel = require('hypixel-api-reborn');
const hypixel = new Hypixel.Client('77684239-5a07-4ea4-bc9c-2f07db9fddb7');
const filePath = 'C:/Users/****/AppData/Roaming/.minecraft/logs/blclient/minecraft/latest.log';
const keyword = 'ONLINE: ';
let lastTrimmed = '';
console.clear();
let win;
function createWindow() {
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
});
win.loadFile('playerstats.html');
}
app.whenReady().then(createWindow);
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
app.on('ready', async () => {
const checkForUpdates = () => {
fs.promises.readFile(filePath, 'utf8')
.then(data => {
if (data.includes(keyword)) {
const index = data.lastIndexOf(keyword);
const line = data.substring(index);
const parts = line.split('\n');
const trimmed = parts[0].trim();
if (trimmed !== lastTrimmed) {
const names = trimmed.split(', ');
names.forEach(async name => {
const playerName = name.replace(keyword, '');
try {
const player = await hypixel.getPlayer(playerName);
const winstreak = player.stats.bedwars.winstreak || '?';
const finalKills = player.stats.bedwars.finalKills;
const fkdr = player.stats.bedwars.finalKDRatio;
const wins = player.stats.bedwars.wins;
const lvl = player.stats.bedwars.level;
win.webContents.executeJavaScript(`
document.getElementById("IGN").innerHTML = "${player}";
document.getElementById("wins").innerHTML = "${wins}";
document.getElementById("finalKills").innerHTML = "${finalKills}";
`);
console.log(`(${lvl})${playerName}: ws - ${winstreak} fkdr - ${fkdr} finals - ${finalKills} wins - ${wins}`);
} catch (err) {
console.error(`${playerName} Is Nicked`);
}
});
lastTrimmed = trimmed;
}
}
})
.catch(console.error);
};
setInterval(checkForUpdates, 1000);
});
<!DOCTYPE html>
<html>
<head>
<title>Player Stats</title>
</head>
<body>
<table>
<tr>
<th>IGN</th>
<th>Wins</th>
<th>Finals</th>
<th>FKDR</th>
</tr>
<tr>
<td id="IGN"></td>
<td id="wins"></td>
<td id="finalKills"></td>
<td id="fkdr"></td>
</tr>
</table>
<script>
const playerData = window.playerData;
document.querySelector("#IGN").textContent = playerData.player;
document.querySelector("#wins").textContent = playerData.wins;
document.querySelector("#final-kills").textContent = playerData.finalKills;
</script>
</body>
</html>
I tried looking at other forums regarding them, but every other user had more complex programs that integrated adding rows, and I couldn't figure out how to implement it into my code.
The forums i found on stackoverflow that were relevant to me only asked about a singular row.
I also thought about just adding 15 more table rows (I only need 16 rows max) but I couldn't figure out how to divert the "getElementById()" to fill out data in a different row.
I'm not sure I understood your problem, but, if you have an array of players, you could do something like:
<script>
for(let i = 0; i < players.lenght; i++) {
let table = document.getElementById("tableId")
let newTr = document.createElement("tr")
let td1 = document.createElement("td")
td1.innerText = players[i].player
let td2 = document.createElement("td")
td2.innerText = players[i].wins
let td3 = document.createElement("td")
td3.innerText = players[i].finalKills
tr.append(td1)
tr.append(td2)
tr.append(td3)
table.append(tr)
}
</script>
This script cycles trough an array of players and for each one of them creates a row in the table with the relative tds.
Notice that you need to give the table an id (tableId in my example) also notice that you could use thead and tbody tags.

API Images not displaying and cards not dynamically populated

I am trying to display Unsplash images on cards.
The cards are created using JavaScript.
The 10 objects from the Unsplash API is shown on the console.
However, I cannot seem to find the problem on why the cards and the API Unsplash images are not displaying.
Appreciate any help, thanks.
const resultsNav = document.getElementById('resultsNav');
const favouritesNav = document.getElementById('favouritesNav');
const imagesContainer = document.querySelector('.images-container');
const saveConfirmed = document.querySelector('.saveConfirmed');
const loader = document.querySelector('.loader');
// Unsplash API
const count = 10;
const apiKey = 'DEMO KEY';
const apiUrl = `https://api.unsplash.com/photos/random?client_id=${apiKey}&count=${count}`;
let resultsArray = [];
function updateDOM() {
resultsArray.foreach((result) => {
// Card Container
const card = document.createElement('div');
card.classList.add('card');
// link
const link = document.createElement('a');
link.href = result.hdurl;
//Images
const image = document.createElement('img');
image.src = result.url;
image.alt = 'Image';
image.loading = 'lazy';
image.classList.add('card-img-top');
//Card Body
const cardBody = document.createElement('div');
cardBody.classList.add('card-body');
// Save Text
const saveText = document.createElement('p');
saveText.classList.add('clickable');
saveText.textContent = 'Add To Favourites';
// Append
cardBody.append(saveText);
link.appendChild(image);
card.append(link, cardBody);
imagesContainer.appendChild(card);
});
}
// Get 10 Images from Unsplash API
async function getUnplashPictures() {
try {
const response = await fetch(apiUrl);
resultsArray = await response.json();
console.log(resultsArray);
updateDOM();
} catch (error) {
// Catch Error Here
}
}
// On Load
getUnplashPictures();
Let's fix the for loop part;
foreach() usage should be with capital E as .forEach() that cause an error and your response objects prop were different named.
let resultsArray = [];
function updateDOM() {
for (let result of resultsArray) {
// Card Container
const card = document.createElement('div');
card.classList.add('card');
// link
const link = document.createElement('a');
link.href = result.links.self;
//Images
const image = document.createElement('img');
image.src = result.urls.small;
image.alt = 'Image';
image.loading = 'lazy';
image.classList.add('card-img-top');
//Card Body
const cardBody = document.createElement('div');
cardBody.classList.add('card-body');
// Save Text
const saveText = document.createElement('p');
saveText.classList.add('clickable');
saveText.textContent = 'Add To Favourites';
// Append
cardBody.append(saveText);
link.appendChild(image);
card.append(link, cardBody);
imagesContainer.appendChild(card);
};
}

Glide.js dynamic append content from Json

I'm trying to add content to the slider dynamically from JSON.
import Glide from '#glidejs/glide';
function slider() {
let ul = document.querySelector('.glide__slides');
let card = '';
var glide = new Glide('.glide').destroy();
const photo = import('../metadata/photos.json').then((module) => {
const data = module.default;
data.forEach((photo) => {
console.log(photo);
card += `<li class="glide__slide"><img src="${photo.thumbnailUrl}" alt="${photo.title}">${photo.id}</li>`;
});
ul.innerHTML = card;
});
glide.mount();
}
slider();
The content seems to load but the slider is not working
That happens because glide.mount(); runs before the import and generate HTML finished.
So, you have to import the data and append it then call glide.mount();.
import Glide from '#glidejs/glide';
function slider() {
let ul = document.querySelector('.glide__slides');
let card = '';
var glide = new Glide('.glide').destroy();
const photo = import('../metadata/photos.json').then((module) => {
const data = module.default;
data.forEach((photo) => {
console.log(photo);
card += `<li class="glide__slide"><img src="${photo.thumbnailUrl}" alt="${photo.title}">${photo.id}</li>`;
});
ul.innerHTML = card;
}).then(() => glide.mount());
}
slider();

Automatically add to DOM when there is new updates

I am trying to create an HTML page where DOM element will automatically update when there are new comments added to the database.
Here is the HTML code
<h1 id="name" style="text-align: center"></h1>
<h2 id="singername" style="text-align: center"></h2>
<textarea id="content"></textarea>
<br />
<button type="submit" id="submitreview" onclick="submitreview()">submit</button>
Here is the Javascript code to add review to the database when click submit:
async function submitreview() {
var selectedone = localStorage.getItem("category");
var selectedtwo = localStorage.getItem("song");
const reviewcontent = document.getElementById("content");
var d = new Date();
e = d.toLocaleString();
g = userID;
namelist = [];
await db.collection("User").doc(g).get().then(function(doc3) {
if (doc3.exists) {
console.log(doc3.data().name_user);
namelist.push(doc3.data());
} else {
console.log("nothing here exist");
}
}).catch(function(error) {
console.log("Error getting document:", error);
});
var username = namelist[0].name_user;
db.collection("Song").doc(selectedone).collection("songs").doc(selectedtwo).collection("reviews").doc().set({
review_content: reviewcontent.value,
review_date: e,
user_id: userID,
user_name: username,
})
document.getElementById("content").value = "";
}
Here is the javascript code to load DOM elements base on the data from database:
async function foo() {
var selectedone = localStorage.getItem("category");
var selectedtwo = localStorage.getItem("song");
var contentresult = [];
await db.collection("Song").doc(selectedone).collection("songs").doc(selectedtwo).collection("reviews").get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc2) {
console.log(doc2.id, " => ", doc2.data());
contentresult.push(doc2.data());
// console.log(doc2.data()[1].review_date.todatestring());
});
})
.catch(function(error) {
console.log("Error getting documents: ", error);
});
console.log(contentresult);
const reviewlist = document.getElementById("reviewlist");
for(let b = 0; b < contentresult.length; b++) {
var node = document.createElement('div');
var size = document.createElement('h2');
var size2 = document.createElement('h2');
var size3 = document.createElement('p');
var breakpoint = document.createElement('br');
var anotherbreakpoint = document.createElement('br');
size.setAttribute('class','left');
size2.setAttribute('class','right');
var text1 = document.createTextNode(contentresult[b].user_name + ' - ');
var text2 = document.createTextNode('- ' + contentresult[b].review_date);
var text3 = document.createTextNode(contentresult[b].review_content);
size.appendChild(text1);
size2.appendChild(text2);
size3.appendChild(text3);
node.appendChild(size);
node.appendChild(size2);
node.appendChild(breakpoint);
node.appendChild(anotherbreakpoint);
node.appendChild(size3);
reviewlist.appendChild(node);
}
}
Right now, I have to reload the page every time I add a comment to see the updates on the page, how can I make it synchronize with the updates from the database. I use Firestore as the database.
There's no real time fetching going on with this code. If you add an listener, it will work. But there is another way. Just call function foo in the end of submitreview. I think it'll be enough. Happy to help :)

Categories

Resources