Glide.js dynamic append content from Json - javascript

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();

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 to dynamically create a new project card with elements that that contain the data the user inputs

I am creating a To-Do-List program in html, css and js.
I want a new project window to appear, containing the user's project name and description after the user clicks the submit button on the form after add project button is clicked.
However I don't see the values of inputName nor inputDescription, in the button's text and the paragraph's text. What am I doing wrong? live code : (https://codepen.io/nolimitz71/pen/QWmBpPm?editors=1010)
JS:
const cancelButton = document.getElementById("cancel");
const projectForm = document.getElementById("projectForm");
const newPage = document.querySelector('.add-project');
const inputName = document.getElementById('project-name');
const inputDescription = document.getElementById('project-description');
const examplePage = document.querySelector(".example-page");
const createdContainer = document.createElement("div");
const projectHolder = document.querySelector(".item-placement");
const createdProject = document.createElement("button");
const container = document.querySelector(".body");
/*Controlling new Project form Open and Close*/
const closeProject = () => {
projectForm.style.display = "none";
};
const openProject = () => {
projectForm.style.display = "block";
};
newPage.addEventListener("click", openProject);
cancelButton.addEventListener("click", closeProject);
const subProjects = (() => {
createdProject.setAttribute("id","change");
createdProject.innerHTML =
`
<ion-icon name="checkmark-circle-outline"></ion-icon>
${inputName.value}
`
projectHolder.appendChild(createdProject);
})();
const LoadProject = (() => {
createdContainer.setAttribute("id",'new-subpage');
createdContainer.setAttribute("data-tab-content", "");
container.appendChild(createdContainer);
const paraName = document.createElement('p');
paraName.textContent= inputName.value;
paraName.classList.add("new-paragraph");
createdContainer.appendChild(paraName);
const paraDesc = document.createElement('p');
paraDesc.textContent= inputDescription.value;
paraDesc.classList.add('new-description');
createdContainer.appendChild(paraDesc);
const newTasks = document.createElement('button');
newTasks.textContent = "Add Task!"
newTasks.classList.add("new-btn");
createdContainer.appendChild(newTasks);
const defaultTask = document.createElement("div");
defaultTask.classList.add("item");
defaultTask.innerHTML= `
<input class = "check" type="checkbox">
<p>Default Task</p>
<div class = 'item-btn'>
<ion-icon class = "black" name="pencil-outline"></ion-icon>
<ion-icon class = "black"name="trash-outline"></ion-icon>
</div>
</div>`
createdContainer.appendChild(defaultTask);
})();
addPage.addEventListener("click", () => {
examplePage.style.display = "none";
createdContainer.style.display = "block";
})
export {closeProject, LoadProject, openProject};

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);
};
}

Create Firebase Blog Post with <iframe>

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();

How do I delete an <li> on click with vanilla javascript?

I'm having trouble finding the right syntax to use to delete an element. I have a list item that I generate with a form that I want to also be deleted when I click on it. Here is my current javascript code:
// add to do items
let todoList = [];
function addTodo(item){
todoList.push(item);
//display item
}
const addButton = document.querySelector('.btn__display');
const formInput = document.querySelector('.addItem');
const listItems = document.querySelectorAll('li');
addButton.addEventListener('click', function(){
const todoUl = document.querySelector('ul');
const todoLi = document.createElement('li');
todoLi.textContent = formInput.value;
todoList.push(formInput.value);
todoUl.appendChild(todoLi);
formInput.value = '';
});
So far I can add an item to my todo list but how do I go about deleting it with a click?
You can add an onclick listener to the newly created li element to remove it when clicked:
todoLi.onclick = (e) => e.target.remove();
// add to do items
let todoList = [];
function addTodo(item) {
todoList.push(item);
//display item
}
const addButton = document.querySelector('.btn__display');
const formInput = document.querySelector('.addItem');
const listItems = document.querySelectorAll('li');
addButton.addEventListener('click', function() {
const todoUl = document.querySelector('ul');
const todoLi = document.createElement('li');
todoLi.textContent = formInput.value;
todoLi.onclick = (e) => e.target.remove();
todoList.push(formInput.value);
todoUl.appendChild(todoLi);
formInput.value = '';
});
<button class="btn__display">btn__display</button>
<input type="text" class="addItem">
<ul></ul>
Similar to Luis's answer, you can do the following:
// add to do items
let todoList = [];
function addTodo(item){
todoList.push(item);
//display item
}
const addButton = document.querySelector('.btn__display');
const formInput = document.querySelector('.addItem');
addButton.addEventListener('click', function(){
const todoUl = document.querySelector('ul');
const todoLi = document.createElement('li');
todoLi.textContent = formInput.value;
todoList.push(formInput.value);
todoUl.appendChild(todoLi);
formInput.value = '';
todoLi.addEventListener('click', function () {
this.remove();
});
});
The difference being that we are instead adding the event listener with a function where this will be set to the list item.
https://jsfiddle.net/gy9cLum3/
Try with this code:
<ul>
<li onclick="remove(this)">lorem</li>
</ul>
<script>function remove(elem) { elem.parentElemet.removeChild(elem); } </script>

Categories

Resources