second question..
I've made a litte feature in Javascript, When you click on my logo, my email is copied.
This one works. Here you got the code.
const btnCopy = document.querySelector('.btn-copy');
const txtCopy = document.querySelector('.box p');
btnCopy.addEventListener('click', () => {
navigator.clipboard.writeText(txtCopy.innerText);
})
<div class="box">
<p style="display: none;">myemail#gmail.com</p>
<button class="btn-copy"><img src="ressources/logo.svg" class="logo"><img src="ressources/logo.svg" class="logo"></button>
</div>
I would like to know how to create an alert when the email is copied..
If you can help me
Thank you, enjoy your weekend :)
navigator.clipboard.writeText() This returns a promise and it can be handled like any async task.
const btnCopy = document.querySelector('.btn-copy');
const txtCopy = document.querySelector('.box p');
btnCopy.addEventListener('click', () => {
navigator.clipboard.writeText(txtCopy.innerText).then(() => {
//show scuccess message.
alert('Email copeid successfully')
}).catch(() => {
//show error message.
alert('Something went wrong!')
});
})
<div class="box">
<p style="display: none;">myemail#gmail.com</p>
<button class="btn-copy"><img src="ressources/logo.svg" class="logo"><img src="ressources/logo.svg" class="logo"></button>
</div>
Related
Hope everyone is well.
This is my HTML code.
<div class="location">
<h1 class="location-timezone">Timezone</h1>
<img src="https://openweathermap.org/img/wn/04n.png" id ="image" alt=""class="icon" />
</div>
By using "openweathermap.org" API, I am trying to get the icon value. I have already got the temperature and other things. But when it comes to change the icon value, it doesnt change.
Below, I have attached my JavaScript code:
const api = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${long}&appid={API KEY}`
fetch(api)
.then(response =>{
return response.json();
})
.then(data => {
console.log(data);
const { icon} = data.weather[0];
iconButton.src=`http://openweathermap.org/img/wn/${icon}.png`
My question is what exactly I am doing wrong. Thanks in advance.
I tested the api, but everything seems to work fine.
It's probably the way you're changing the iconButton.src.
See if this sample helps:
var sample = {"coord":{"lon":145.77,"lat":-16.92},"weather":[{"id":802,"main":"Clouds","description":"scattered clouds","icon":"03n"}],"base":"stations","main":{"temp":300.15,"pressure":1007,"humidity":74,"temp_min":300.15,"temp_max":300.15},"visibility":10000,"wind":{"speed":3.6,"deg":160},"clouds":{"all":40},"dt":1485790200,"sys":{"type":1,"id":8166,"message":0.2064,"country":"AU","sunrise":1485720272,"sunset":1485766550},"id":2172797,"name":"Cairns","cod":200};
const { icon } = sample.weather[0]
document.querySelector('button').addEventListener('click', () => {
document.querySelector('.icon').src = `https://openweathermap.org/img/wn/${icon}.png`
})
<div class="location">
<h1 class="location-timezone">Timezone</h1>
<img src="https://openweathermap.org/img/wn/04n.png" id="image" alt="" class="icon" />
</div>
<button>Fetch new weather</button>
I am new to working with APIs in javascript. I am looking to get input that a user puts into a box on a site (a city name) and fetch the API, to retrieve the temperature in that city. So far I have the following to fetch the API. But I am a bit lost on how to actually get that data and display it. How would I get the 'data'? I'm just not used to using APIs with Javascript and looking to learn more.
js file:
function hi() {
function temperature(input) {
const myKey = "Hidden_for_privacy";
const api = `https://api.openweathermap.org/data/2.5/weather?
q=${input}&lang=en&&appid=${myKey}&units=metric`;
fetch(api)
.then(function(response){
let data = response.json();
console.log(data);
return data;
})
Then I have this. searchUser is just representing the location the user types in:
const search = document.getElementById("searchUser");
const button = document.getElementById("submit");
button.addEventListener("click", () => {
const currentVal = search.value;
Relevant HTML:
<div class="container searchContainer">
<div class="search card card-body">
<h3>Get The Weather For a Location</h3>
<p class="lead">Enter Your Location</p>
<input type="text" id="searchUser" class="form-control"
placeholder="Location">
</div>
<br>
<div id="profile"></div>
</div>
<div class="container text-center mt-2">
<button class="btn btn-primary" id="submit">Submit</button>
</div>
<div id="content">
</div>
I think you have a few syntax errors going on before you can get into displaying data on the screen. I'd suggest concentrating on the JS implementation first to ensure you are successfully fetching data and loading it to the console. For instance, the closures in your JS might be causing problems. The hi function is creating a closure and then you are passing an argument of input into a function inside it but there is no local variables for it to grab.
Maybe try something like this to start and see what it logs:
function getTemperature() {
const myKey = "Hidden_for_privacy";
const api = `https://api.openweathermap.org/data/2.5/weather?
q=${input}&lang=en&&appid=${myKey}&units=metric`;
// .json returns a promise so you need to use .then to get the data from it synchronously
fetch(api)
.then((response) => response.json())
.then(data => console.log(data))
}
I have the following JavaScript method for loading the messages in a mini chat app. The idea is that I have two HTML classes to position the message either on left or right depending on who sent it. The HTML and CSS are fine and work properly. My question is when it comes down to getting the messages from Firestore.
I have the following messages in order from first sent to last: Hello, hyd?, Good, Hello Sir, hey
But somehow strangely they are not ordered properly when displayed on the screen, I get first the messages sent from other user then it displays my messages. I am not sure where I messed up the code for this behavior but I somehow believe it has to do with the if statement where I check who sent the message. The document of a message in Firestore has the following structure:
{
createdAt: ....,
message: ....,
from: ....,
to: ....
}
let divMessagesLeft = document.getElementById("firstmessages--main-div-id");
let devMessagesRight = document.getElementById("firstmessages--main-div-id-2");
async function loadMessages() {
firebase.auth().onAuthStateChanged(async function (user) {
if (user) {
let messagesReference = firebase
.firestore()
.doc(`/chats/${user.displayName}`)
.collection(`/chats/${userChat.username}/messages`)
.orderBy("createdAt");
await messagesReference
.get()
.then(function (snapshot) {
snapshot.forEach(function (doc) {
console.log(doc.data().message);
if (doc.data().from === userChat.username || doc.data().to === user.displayName) {
const message = `<div class="messagee">${doc.data().message}</div>`;
divMessagesLeft.innerHTML += message;
} else {
const message = `<div class="messagee messagee-right">${doc.data().message}</div>`;
devMessagesRight.innerHTML += message;
}
});
});
} else {
console.log("Not logged in");
}
});
}
loadMessages();
<div id="chat-messages-main-div-id" class="chat-messages-main-div">
<div id="first-message-div-id" class="first-message-div">
<div id="firstmessages--main-div-id" class="firstmessages--main-div">
<!-- <div class="messagee">Hello</div> -->
</div>
</div>
<div id="first-message-right-id-2" class="first-message-right">
<div id="firstmessages--main-div-id-2" class="firstmessages--main-div">
<!-- <div class="messagee messagee-right">Hi</div> -->
</div>
</div>
</div>
I would try to replace the "||" operator with "&&", which is a more correct check to do.
(it will fail if you'll try messaging yourself, and you should think how you want to implement this scenario).
Also I think you need to add "desc" to the "order by" method.
I'm creating a project with the use of Firebase and I'm having some issues with getting the data inside of my database to display in the DOM due to error "setupFoodGroup is not defined"...This is likely due to a rookie coding error, but I can't seem to work out where I've gone wrong.
Current code as per below:
// Get data from database
db.collection('foodgroups').get().then(snapshot => {
setupFoodGroup(snapshot.docs);
});
// Setting Up Food Lists
const foodList = document.querySelector('.foodGroups');
const setupFoodGroup = (data) => {
let html = '';
data.forEach(doc => {
const group = doc.data();
const li = `
<li>
<div class="card bg-light mb-3" style="max-width: 20rem;">
<div class="card-body">
<h4 class="card-title">${group.title}</h4>
<p class="card-text">${group.content}</p>
</>
</div>
</li>
`;
html += li
})
foodGroups.innerHTML = html;
};
I'm then wanting to get them displaying inside the following HTML on a display page
<div class="card-body">
<ul class="foodGroups">
</ul>
</div>
Any points would be very much appreciated.
Cheers!
I am trying to get the button below with addEventListener. How ever it returns null. The html is rendered from js using template string. So what I am trying to achieve is to addEventListener to delete button inside the template string.
// This is the template string
data.forEach(doc => {
checkin = doc.data();
card = `
<div class="carousel-item fieldId" data-id="${doc.id}">
<div class="col-12">
<div class="card checkCard" style="margin: 0 auto;">
<img src="${checkin.photo}" class="card-img-top" alt="...">
<button type="submit" class="btn center delete">
<i class="material-icons" style="font-size: 1em;">delete_forever</i>
</button>
<div class="card-body">
<h5 class="card-title">${checkin.title}</h5>
<p class="card-text">${checkin.description}</p>
</div>
</div>
</div>
</div>
`;
html += card;
});
checkinList.innerHTML = html;
//This is the delete button
const deleteContent = document.querySelector('.delete');
deleteContent.addEventListener('click', (e) => {
// get current document ID
console.log('hmm')
e.stopPropagation();
let id = $('.carousel-item').attr('data-id')
db.collection("checkin").doc(id).delete().then(() => {
console.log(id + "successfully deleted!");
$('.carousel-item').attr('data-id')
}).catch(function (error) {
console.error("Error removing document: ", error);
});
});
And this is the erro from the console
Uncaught TypeError: Cannot read property 'addEventListener' of null
at index.js:123
(anonymous) # index.js:123
Hopefully I've outlined all the changes I made to get this to work:
As was pointed out in comments, IDs must be unique. Classes are generally better to use as JavaScript (and CSS) hooks. Many people now use a js- prefix for these to help follow the logic from HTML -> JS when maintaining code so I would suggest this.
document.querySelector('.delete') will only get a single element - you need querySelectorAll here, since you will have a delete button for each item.
$('.carousel-item') is (I'm assuming) a jQuery function call. This will get all .carousel-item elements in the document and .attr('data-id') will get the attribute of only the first one. If you wanted to use jQuery here, you would want to go up the DOM from the button element like $(e.target).parent('.carousel-item'). But, since the other code isn't using jQuery, it would be more consistent to use e.target.closest('.js-carousel-item'), imo. Then, to get data-id, we can easily use element.dataset.id.
Don't use globals for this like sao suggested
I'm not sure if data in your example came from a call to db.collection('checkin').get(), but if it was a Promise in your code, instead of the snapshot itself, you would run into problems if your delete button code wasn't nested in the then() callback.
This is more of an optional side-note, but your code could become more readable by refactoring it to use async/await.
I've included a working snippet based on your example below to demonstrate:
;(() => {
// My attempt at a quick mock of Firebase to make this work as a snippet
const db = {
_collections: {
'checkin': [
{
id: 1,
photo: 'https://images.unsplash.com/photo-1508138221679-760a23a2285b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1267&q=80',
title: 'airplane w/ trees',
description: 'airplane on ground surrounded with trees',
}, {
id: 2,
photo: 'https://images.unsplash.com/photo-1485550409059-9afb054cada4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=701&q=80',
title: 'head to head',
description: 'minifigure head lot',
},
],
},
collection(key) {
const c = this._collections[key];
const doc = (id) => ({
id,
data() {
return c.find(o => o.id === id);
},
async delete() {
const idx = c.findIndex(o => o.id === id);
c.splice(idx, 1);
},
});
return {
doc,
async get() {
return c.map(o => o.id).map(doc);
},
};
},
}
const render = () => {
db.collection('checkin').get().then(snapshot => {
const cards = snapshot.map(doc => {
const checkin = doc.data();
return `
<div class="js-carousel-item carousel-item fieldId" data-id="${doc.id}">
<div class="col-12">
<div class="card checkCard" style="margin: 0 auto;">
<img src="${checkin.photo}" class="card-img-top" alt="...">
<button class="js-delete" type="submit" class="btn center">
<i class="material-icons" style="font-size: 1em;">delete_forever</i>
</button>
<div class="card-body">
<h5 class="card-title">${checkin.title}</h5>
<p class="card-text">${checkin.description}</p>
</div>
</div>
</div>
</div>`;
});
document.querySelector('.js-checkin-list').innerHTML = cards.join('');
// This is the delete button
const deleteButtons = document.querySelectorAll('.js-delete');
const deleteHandler = (e) => {
e.stopPropagation();
const el = e.target.closest('.js-carousel-item');
const id = +el.dataset.id;
db.collection('checkin').doc(id).delete().then(() => {
console.log(`${id} successfully deleted!`);
}).catch((error) => {
console.error('Error removing document: ', error);
})
render();
}
deleteButtons.forEach(
btn => btn.addEventListener('click', deleteHandler)
);
});
};
render();
})();
<div class="js-checkin-list carousel"></div>
use onclick inline in your string
for example
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="parentDiv"></div>
</body>
<script>
let element = `<div id="childDiv" onclick="myFunction()">click here</div>`;
document.getElementById("parentDiv").innerHTML = element;
function myFunction() {
console.log("works every time");
}
</script>
</html>
now the child div gets inserted into the parent and is has an onclick event listener
if you want it to loop, don't loop the addEventListener in JS, loop it in the template literal, in other words, just add this in your string not an extra function.
i just tested it and it works..every...time
have fun!