How to add bg image to API weather project? - javascript

Hello lately i've been working with APIs to get the hang of them through the usual weather app project BUT i'm pretty much still a beginner in javascript and i was wondering how to add a background image that matches the weather report of the city selected by the user.
I wanted to create many classes in css, each called like the weather (ex: .clear, .clouds,.rain etc...) and then use a classList.add() method to change it each time depending on the openWeatherMap data. I tried adding something like document.getElementsByTagName("body")[0].classList.add(weatherValue); inside the .then promise but it doesn't work. Can somebody help me? If there's a much simpler way i'd like to hear about it too :) Thank you so much
var button = document.querySelector(".button");
var inputValue = document.querySelector(".inputValue");
var cityName = document.querySelector(".name");
var weather = document.querySelector(".weather");
var desc = document.querySelector(".desc");
var temp = document.querySelector(".temp");
var humi = document.querySelector(".humi");
button.addEventListener("click", function() {
fetch("https://api.openweathermap.org/data/2.5/weather?q="+inputValue.value+"&appid={myapikey}")
.then(response => response.json())
.then(data => {
var nameValue = data['name'];
var weatherValue = data['weather'][0]['main'];
var tempValue = data['main']['temp'];
var descValue = data['weather'][0]['description'];
var humiValue = data['main']['humidity'];
cityName.innerHTML = nameValue;
weather.innerHTML = weatherValue; // this gives "clear" "clouds" etc to <p> element
desc.innerHTML = descValue;
temp.innerHTML = "Temperature: " + tempValue;
humi.innerHTML = "Humidity: " + humiValue;
})
.catch(err => alert("Wrong city name!"))
})
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Nunito", sans-serif;
background-repeat: no-repeat;
background-size: cover;
}
.input {
text-align: center;
margin: 100px 0;
}
input[type="text"] {
height: 50px;
width: 600px;
background: #e7e7e7;
font-family: "Nunito", sans-serif;
font-weight: bold;
font-size: 20px;
border: none;
border-radius: 2px;
padding: 10px 10px;
}
input[type="submit"] {
height: 50px;
width: 100px;
background: #e7e7e7;
font-family: "Nunito", sans-serif;
font-weight: bold;
font-size: 20px;
border: none;
border-radius: 2px;
}
.display {
text-align: center;
}
.clear {
/* background image here */
}
.clouds {
/* another background image here */
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="weather_app.css">
</head>
<body>
<div class="input">
<input type="text" class="inputValue" placeholder="Enter a city">
<input type="submit" value="Submit" class="button">
</div>
<div class="display">
<h1 class="name"></h1>
<p class="weather"></p>
<p class="desc"></p>
<p class="temp"></p>
<p class="humi"></p>
</div>
<script src= "weather_app.js"></script>
</body>
</html>

I did a project like this not long ago, https://github.com/Kroplewski-M/Weather-App , I used the openWeater API. I did this:
function setBackground(weather) {
if (weather == "Rain") {
background.src = "./resources/rainy-weather.jpg";
} else if (weather == "Snow") {
background.src = "./resources/snowy-weather.jpg";
} else if (weather == "Clear") {
background.src = "./resources/sunny-weather.jpg";
} else if (weather == "Clouds") {
background.src = "./resources/cloudy-weather.jpg";
}
}
The openWeather API returns what condition the weather is so you can just if statement on what the condition is and set the background accordingly

Related

looking for why list does not display when adding task to the to do

Good day folks,
I am creating a to-do app, and so far when I enter the task in via the input the console shows my object firing but does not display it on the screen. Please look at my code and help me point out the issue, I have been debugging this for some time today.
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/to-doStylesheet.css">
<title>To-Do App</title>
</head>
<body>
<div class=container>
<div class= base>
<div class = screen>
<img src="images/WarGreymon_Render.png" alt="Wargreymon">
<div id ="speach-bubble"> What is on your
agenda for today?
</div>
<div class = "dateTime">
</div>
</div>
<div class = "nameInput" id = "inputContainer">
<form class ="form">
<input type="text" class ="userInput" placeholder="Add Agenda and press enter">
<input type="submit" value ="Add">
</form>
</div>
</div>
<ul class="list"></ul>
<script src="js/add-task.js"></script>
</body>
</html>
CSS
.form
{
margin-left: 400px;
}
.userInput
{
width: 394px;
height: 30px;
background-color: #B62626;
font-family: Digimon Basic;
color: #33D61A;
margin-left: -359px;
}
.userInput ::placeholder
{
color: #33D61A;
font-family: Digimon Basic;
}
.list:empty
{
display: none;
}
.list
{
list-style: none;
margin-bottom: 20px;
}
.input[type="checkbox"] {
display: none;
}
.tick {
width: 30px;
height: 30px;
border: 3px solid #333;
border-radius: 50%;
display: inline-flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.todo-item {
margin-bottom: 10px;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.todo-item span {
flex-grow: 1;
margin-left: 10px;
margin-right: 10px;
font-size: 22px;
}
JS
let tasks = [];
const currentdt = new Date()
function todo(text) {
const todo = {
text,
checked: false,
id: Date.now(),
timestamp: currentdt
};
tasks.push(todo);
console.log(tasks);
}
// Select the form element
const form = document.querySelector('.form');
// Add a submit event listener
form.addEventListener('submit', event => {
// prevent page refresh on form submission
event.preventDefault();
// select the text input
const input = document.querySelector('.userInput');
// Get the value of the input and remove whitespace
const text = input.value.trim();
if (text !== '') {
todo(text);
input.value = '';
input.focus();
}
});
//This function is to display new to do on the screen
function displaytasks(todo)
{
const list = document.querySelector('list');
const isChecked = todo.checked ? 'done': '';
const addedList = document.createElement("li");
addedList.setAttribute('class', `todo-item ${isChecked}`);
addedList.setAttribute('data-key', todo.timestamp);
addedList.innerHTML = `<input id="${todo.timestamp}" type="checkbox"/>
<label for="${todo.timestamp}" class="tick js-tick"></label>
<span>${todo.text}</span>
<button class="delete-todo js-delete-todo">
<img class = "delete" src="images/delete.png" alt="delete icon">
</button>`;
list.append(addedList);
}
So I am busy with the js file at the moment, I think it has to do something with the innerHTML, but I am not sure what exactly is wrong there, because when I look in the console on the HTML side I do not see the <ul class="list"></ul> firing at all to bring the new HTML elements.
Your help will be much appreciated
It looks like the code to display the todos is not being called, so I would recommend you add in a function call after reading in a new todo.
...
const text = input.value.trim();
if (text !== '') {
todo(text);
input.value = '';
input.focus();
displaytasks(tasks); // Show tasks after submission
}
});
//This function is to display new to do on the screen
function displaytasks(todo)
{
const list = document.querySelector('.list');
...

How to reload page without losing any data

I am pretty new to web development and I am making this little project that consists in a little site that allows a user to add and remove their goals(kinda like a to do list)
I want to implement a last feature that allows the browser to save the content of the page, so that if the user reloads the page, he/she does not lose track of their goals. I tried using local storage but it's not working.
Any suggestion/tips on how to tackle such problem?
Thank you very much and I apologise, in advance for the code smell.
var i = 0
var j =0
var parentElement = document.getElementById('new-goals')
function addGoal(){
var userGoal = window.prompt('Enter goal: ')
var divTag = document.createElement('div')
divTag.className = 'goalsSection'
divTag.id = 'goal- ' + i
i++
var goal = document.createElement('p')
goal.innerHTML = userGoal
goal.className= 'usergoal'
goal.id = 'UserGoal'+j
var del = document.createElement('button')
del.className = 'deleteButton'
del.innerHTML = 'Delete Goal'
del.id = j
var com = document.createElement('button')
com.className = 'completedButton'
com.innerHTML = 'Not Completed'
com.id = j
j++
com.onclick = function(e){
if (com.innerHTML == 'Not Completed' ){
var dec = window.prompt('Are you sure? this action can not be undo type y/n')
if (dec == 'y'){
com.innerHTML = 'Completed'
var ele = e.target.id
var fin = 'UserGoal'+ele
document.getElementById(fin).style.textDecoration='line-through'
}
}
}
divTag.appendChild(goal)
divTag.appendChild(del)
divTag.appendChild(com)
parentElement.appendChild(divTag)
del.onclick = function(e){
var id_toDelete = e.target.id
var id_section = 'goal- ' + id_toDelete
alert(id_section)
parentElement.removeChild(divTag)
}
}
body{
background-color: #003f5c;
}
h1{
display: flex;
justify-content: center;
font-size: 60px;
font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
}
.btnConatiner{
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 40px;
}
#newGoalBtn{
display: flex;
justify-content: center;
align-items: center;
width: 200px;
height: 50px;
font-size: 30px;
border-radius: 15px;
border: solid 5px black;
cursor: pointer;
}
.goalsSection{
border: solid 6px white;
width: 200px;
height: 100px;
border-radius: 20px;
background-color: white;
margin: 10px;
float: left;
}
.usergoal{
text-align: center;
font-size:20px;
}
.deleteButton{
cursor: pointer;
}
.completedButton{
cursor: pointer;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Goal Tracker</title>
</head>
<body>
<h1>Goal Tracker</h1>
<div class="btnConatiner">
<button id="newGoalBtn" onclick="addGoal()">New Goal</button>
</div>
<section class="add-goals">
<div id="new-goals">
</div>
</section>
<script src="app.js"></script>
</body>
</html>
Inside the function addGoal, you can get all the goals that are already on the localstorage, and then push a new goal into the array and store.
// const goals = localStorage.getItem("goals") || []; // you can declare here too.
function addGoal() {
const goals = localStorage.getItem("goals") || [];
const userGoal = window.prompt("Enter goal:")
goals.push(userGoal)
localStorage.setItem('goals', JSON.stringify(goals)) // you need to transform into string
...
And then you can create a function to render the goals that are on the localstorage, like:
function renderGoals() {
const goals = JSON.parse(localStorage.getItem("goals")); // parsing back
// Then you can iterate on these goals (forEach for example) to render.
...
}
You can use localStorage, but not to store all the HTML you're creating, rather to store the essential data. And from that data, you can easily rebuild your html.
First keep track of your data, and set up your addGoal function to accept an argument for the rebuilding (after page refresh)
let userGoals = [] // leave this empty for the moment
function addGoal(userGoal){
if (!userGoal) { // this is a new one, so we'll store it in the array and localStorage
userGoal = window.prompt('Enter goal: ')
userGoals.push(userGoal);
localStorage.setItem('userGoals', JSON.stringify(userGoals)); // localStorage stores everything as strings so we stringify it
}
//... the rest of this function
Then at the bottom of your script, create a window.onload function that runs once, when the page first loads. If there is data in localStorage, this will create your User Goals list
window.onload = function() { // this runs after the page has loaded
if (localStorage.getItem('userGoals') ) { // if we have localStorage values waiting for us, parse them and iterate through them
JSON.parse(localStorage.getItem('userGoals')).forEach(goal => {
userGoals.push(goal)
addGoal(goal)
});
}
}
...

5 day weather forecast on openweathermap not giving expected result

I'm trying to fetch a 5-day weather forecast by using JS Fetch API, though I'm passing cnt=5 as stated in the documentation, Still, I'm getting only current weather. Am I missing anything?
fetch('https://api.openweathermap.org/data/2.5/weather?q=' + city+ '&appid=' + key+'&cnt=5')
I have done enough research and couldn't able to figure out where exactly I'm doing a mistake. Any help is appreciated.
const key = '**** Your API Key Here ****';
function weatherForecast(city) {
fetch('https://api.openweathermap.org/data/2.5/weather?q=' + city+ '&appid=' + key+'&cnt=5')
.then(function(resp) {
return resp.json()
})
.then(function(data) {
console.log('--->'+(JSON.stringify(data)));
drawWeather(data);
})
.catch(function() {
// catch any errors
});
}
function drawWeather( d ) {
var celcius = Math.round(parseFloat(d.main.temp)-273.15);
var fahrenheit = Math.round(((parseFloat(d.main.temp)-273.15)*1.8)+32);
var description = d.weather[0].description;
document.getElementById('description').innerHTML = description;
document.getElementById('temp').innerHTML = fahrenheit + '°';
document.getElementById('location').innerHTML = d.name+' '+d.sys.country;
}
//Event Listeners on button click
document.addEventListener("DOMContentLoaded", () => {
// Handling button click
document.querySelector(".button-search").addEventListener("click", () => {
const searchedCity = document.querySelector('.text-search');
console.log(searchedCity.value);
if(searchedCity.value){
weatherForecast(searchedCity.value);
}
})
});
body {
font-family: 'Montserrat', sans-serif;
font-weight: 400;
font-size: 1.3em;
height: 100vh;
}
h1 {
margin: 0 auto;
font-size: 2.2em;
text-align: center;
font-size: 10em;
}
.main-container,.search-component{
display: flex;
align-items: center;
justify-content: center;
margin: 2em;
}
.text-search{
width: 100%;
max-width: 280px;
padding: 10px 15px;
border: solid blueviolet;
color: #313131;
font-size: 20px;
font-weight: 300;
transition: 0.2s ease-out;
}
.button-search{
font-size: 32px;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Current Weather</title>
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,900" rel="stylesheet">
<link href="style.css" rel="stylesheet">
</head>
<body>
<div class="search-component">
<input type="text" autocomplete="off" class="text-search" placeholder="Type the City Name..." >
<input type="button" class="button-search" value="Search">
</div>
<div class="main-container">
<div>
<div id="description"></div>
<h1 id="temp"></h1>
<div id="location"></div>
</div>
<div>
<script src="main.js"></script>
</body>
</html>
Here is the JSON response I'm getting.
{
"coord":{"lon":-74.01,"lat":40.71},
"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],
"base":"stations",
"main":{
"temp":303.24,
"feels_like":306.4,
"temp_min":301.48,
"temp_max":304.82,
"pressure":1011,
"humidity":74
},
"visibility":10000,
"wind":{"speed":4.6,"deg":260},
"clouds":{"all":1},
"dt":1596415305,
"sys":{
"type":1,
"id":4610,
"country":"US",
"sunrise":1596362046,
"sunset":1596413419
}
"timezone":-14400,
"id":5128581,
"name":"New York",
"cod":200
}
For a 5-day weather forecast you need call /forecast instead of /weather endpoint.
Example:
https://api.openweathermap.org/data/2.5/forecast?q=New%20York&appid=<your-api-key>&cnt=5

Save contentEditable into html file with javascript

How can I save contenteditable element with javascript(no PHP) into actual HTML code? So I can edit content whenever even in offline mode.
Like when you click "save button" it replace old file with new one(text with changes).
If there is a way to make this work in offline mode with any other programming lang please suggest.
I found a few examples but they were all made with PHP.
Also, I will post code. In this code, you are able to edit the file with javascript and save it. But problem is that it does not save into actual HTML code.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title of the document</title>
</head>
<style type="text/css">
body{
font-family: "Dosis";
font-size: 1.3em;
line-height: 1.6em;
}
.headline{
font-size: 2em;
text-align: center;
}
#wrapper {
width: 600px;
background: #FFF;
padding: 1em;
margin: 1em auto;
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
border-radius: 3px;
}
button {
border: none;
padding: 0.8em;
background: #F96;
border-radius: 3px;
color: white;
font-weight: bold;
margin: 0 0 1em;
}
button:hover, button:focus {
cursor: pointer;
outline: none;
}
#editor {
padding: 1em;
background: #E6E6E6;
border-radius: 3px;
}
</style>
<body>
<div id="wrapper">
<section>
<h1 class="headline">contentEditable Demonstration</h1>
<button id="editBtn" type="button">Edit Document</button>
<div id="editDocument">
<h1 id="title">A Nice Heading.</h1>
<p>Last Edited by <span id="author">Monty Shokeen</span>
</p>
<p id="content">You can change the heading, author name and this content itself. Click on Edit Document to start editing. At this point, you can edit this document and the changes will be saved in localStorage. However, once you reload the page your changes will be gone. To fix it we will have to retrieve the contents from localSotrage when the page reloads.</p>
</div>
</section>
</div>
<script>
var editBtn = document.getElementById('editBtn');
var editables = document.querySelectorAll('#title, #author, #content');
if (typeof(Storage) !== "undefined") {
if (localStorage.getItem('title') !== null) {
editables[0].innerHTML = localStorage.getItem('title');
}
if (localStorage.getItem('author') !== null) {
editables[1].innerHTML = localStorage.getItem('author');
}
if (localStorage.getItem('content') !== null) {
editables[2].innerHTML = localStorage.getItem('content');
}
}
editBtn.addEventListener('click', function(e) {
if (!editables[0].isContentEditable) {
editables[0].contentEditable = 'true';
editables[1].contentEditable = 'true';
editables[2].contentEditable = 'true';
editBtn.innerHTML = 'Save Changes';
editBtn.style.backgroundColor = '#6F9';
} else {
// Disable Editing
editables[0].contentEditable = 'false';
editables[1].contentEditable = 'false';
editables[2].contentEditable = 'false';
// Change Button Text and Color
editBtn.innerHTML = 'Enable Editing';
editBtn.style.backgroundColor = '#F96';
// Save the data in localStorage
for (var i = 0; i < editables.length; i++) {
localStorage.setItem(editables[i].getAttribute('id'), editables[i].innerHTML);
}
}
});
</script>
</body>
</html>
You'll want to use something like the downloadInnerHtml function as described here. Ideally you'll probably also want to strip out the script tag and content editable attribute before exporting because you won't want the final html page to be editable

Cannot call method 'getElementsByTagName' of null

This is my first AJAX and my first use of .php file. I'm following an exercise in the text and it's not working. I tried to use the alert function as many times as possible to check what is feeding in to variables and functions, but I'm really unsure what's going on in the background. I checked the Yahoo! Weather RSS feed which is supposed to give this website some information ("http://weather.yahooapis.com/forecastrss?p=94558") and I do see the "item" tag. The console keeps saying "Cannot call method 'getElementsByTagName"!! Appreciate any input in advance....
<!DOCTYPE html PUBLIC "-\\W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Weather Report</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<style type="text/css">
html {
height: 100%;
margin: 0;
padding: 0;
}
body
{
height: 100%;
margin: 0;
padding: 0;
}
a { color: #91c056; }
a:link { color: #515151; text-decoration: none; }
a:visited { color: #515151; text-decoration: none; }
a.back:hover { color: #6eece3; }
#content-pane{
font-family: Courier New, monospace;
letter-spacing: -0.05em;
font-size: 15px;
line-height: 23px;
float:left;
width:100%;
padding-left: 5%;
padding-top: 5%;
}
#headline
{
font-family: Helvetica, "Helvetica Neue", Arial, sans-serif;
font-weight: bold;
letter-spacing: -0.05em;
font-size: 60px;
line-height: 60px;
color: #323232;
text-align: left;
}
</style>
<script type="text/javascript">
/* <![CDATA[ */
var weatherRequest = false;
function getRequestObject(){
try {
httpRequest = new XMLHttpRequest();
}
catch (requestError){
try {
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (requestError) {
try{
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (requestError){
window.alert("Your browser does not support AJAX!");
return false;
}
}
}
return httpRequest;
}
function weatherUpdate(){
if(!weatherRequest)
weatherRequest = getRequestObject();
var zip = document.forms[0].zip.value;
weatherRequest.abort();
weatherRequest.open("get", "WeatherReport.php?zip=" + zip, true);
weatherRequest.send(null);
weatherRequest.onreadystatechange=fillWeatherInfo;
}
function fillWeatherInfo(){
if (weatherRequest.readyState == 4 && weatherRequest.status == 200){
var weather = weatherRequest.responseXML;
var weatherItems=weather.getElementsByTagName("item");
if (weatherItems.length > 0){
for (var i=0; i<weatherItems.length; ++i){
var curHeadline = weatherItems[i].getElementsByTagName("title")[0].childNodes[0].nodeValue;
var curLink = weatherItems[i].getElementsByTagName("link")[0].childNodes[0].nodeValue;
var curPubDate = weatherItems[i].getElementsByTagName("pubDate")[0].childNodes[0].nodeValue;
var curDesc = weatherItems[i].getElementsByTagName("description")[0].childNodes[0].nodeValue;
var weatherSpot = document.getElementById('weatherPara');
var curStory = "<a href='" + curLink + "'>" + curHeadline + "</a><br />";
curStory += "<span style='color: gray'>";
curStory += curDesc + "<br />";
weatherSpot.innerHTML = curStory;
}
}
else
window.alert("Invalid ZIP code.");
}
}
/* }]> */
</script>
</head>
<body onload ="weatherUpdate()">
<div id="content-pane">
go back
<div id="headline">Weather Report</div>
<br />
<br />
<br />
<br />
<form method="get" action="">
<p>ZIP code <input type="text" name="zip" value="94558"/> <input type="button" value="Check Weather" onclick="weatherUpdate()" /></p>
</form>
<p id="weatherPara"></p>
</div>
</body>
</html>
Below is the WeatherReport.php file.
<?php
$Zip = $_GET["zip"];
$WeatherURL
= "http://weather.yahooapis.com/forecastrss?p=" . $Zip;
header("Content-Type: text/xml");
header("Content-Length: " . strlen(file_get_contents($WeatherURL)));
header("Cache-Control: no-cache");
readfile($WeatherURL);
?>
Try adding your WeatherReport.php in form action. You have to specify your php file in you action otherwise the form will point to the same file.
In your function fillWeatherInfo, you haven't passed it any parameters. Therefore, I believe weatherRequest.responseXML is an empty object.
In your onreadystatechange property, you need to pass in the parameters of the AJAX response to the handler.

Categories

Resources