I had to create a "fake" weather page using Javascript only. I am struggling with the layout and have a couple of questions:
I tried everything to include padding above my "h1" title but nothing works.
I want the weather photos and infos to display in the middle of the box (as it does in day0) but I cannot get it to do it.
Would you recommend to break my .js file into different ones for each function or is it ok to put it all in one. I want to avoid it being confusing ?
HTML:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>AccuMeteo</title>
<meta name="description" content="AccuMeteo Weather Forecast">
<meta name="keywords" content="Daily and Weekly Weather forecast">
<link href="css/accumeteo.css" rel="stylesheet">
<script type="text/javascript" src="js/accumeteo.js"></script>
</head>
<body>
<!-- wrapper section starts -->
<div id="wrapper">
<!-- header section starts -->
<div id="header">
<img src="images/header.jpg" width="975" height="220" alt="Blue Sky Header" class="floatleft">
</div>
<!-- header section ends -->
<!-- menu section starts -->
<div id="menu">
<ul>
<li>Home</li>
<li>Vancouver</li>
<li>Dallas</li>
<li>New York</li>
<li>Contact Us</li>
</ul>
</div>
<!-- menu section ends -->
<div id="content">
<div id="city">
<h1>Vancouver, BC</h1>
</div>
<div id="date">
<noscript> <div>! JavaScript is not enabled.</div> </noscript>
<div id="PST"></div>
<div id="year"></div>
<div id="ordinal"></div>
<div id="day"></div>
</div>
<div id="panel">
<div id="day0">
</div>
<div id="day1">
</div>
<div id="day2">
</div>
<div id="day3">
</div>
<div id="day4">
</div>
<div id="day5">
</div>
<div id="day6">
</div>
</div>
</div>
<!-- footer section starts -->
<div id="footer">
<p class="bottom">Copyright © 2012 JC Design | All Rights Reserved | Terms and Conditions</p>
</div>
<!-- foot section ends -->
<!-- wrapper section starts -->
<script>
displayTime("PST");
</script>
</div>
</body>
</html>
.css
/*Homepage* /
/*Body*/
html {background-color: #e2e2e2}
body {
color: #000; background: #fff;
font-family: Verdana,helvetica,arial, sans-serif;
font-size: 90%;
text-align: left;
width: 975px;
margin-left: auto;
margin-right: auto;
}
p {
margin-left: 35px;
margin-right: 25px;
text-align: left;
}
/*---------------Navigation styles-------------------*/
#menu {
float: left;
margin:0;
padding-top: 0px;
width: 100%;
background: #4186d3; color: #04356c;
}
#menu ul {
margin: 0px;
position: relative
}
#menu ul li {
display: inline;
}
#menu ul li a {
float: left;
padding: 5px 16px;
margin-right: 0px;
background: #4186d3; color: #04356c;
text-decoration: none;
border-right: 1px solid #e2e2e2;
}
#menu ul li a:hover {
color: #04356c; background: #fff;
text-decoration: underline;
}
#menu li a#current {
background: #0d56a6; color: #fff;
}
/*Bottom link formatting*/
p.bottom a:link {
background: #04356c; color: #fff;
}
p.bottom a:visited {
color: #ba1212;
}
p.bottom a:hover {
color: #f9b41f;
text-decoration: none;
}
p.bottom a:active{
background: #3ca0d0; color: #000;
}
/*Page wrapper*/
#wrapper {
margin: 0 auto;
width: 975px;
text-align: left;
}
/*Banner styles*/
#header {
background-color: #2d1d06; color: #7d890d;
font-family: verdana, helvetica, arial, sans-serif;
font-size: 150%;
width: 925px;
padding: 0px;
}
#footer {
clear: both;
background: #04356c; color: #fff;
font-family: Verdana,helvetica, arial, sans-serif;
font-size: 90%;
font-weight: normal;
width: 975px;
padding-bottom: 3px;
padding-top: 3px;
}
#footer p {
text-align: center;
}
.content {
padding: 0px 0px 0px 160px;
position: relative;
}
/* Images*/
img {
border: 0px;
padding: 0px;
}
.floatleft {
float: left;
margin: 0px;
padding: 0px;
border: none;
}
/*Headings*/
hr{
position: absolute;
width: 45%;
margin-left: 35px;
margin-right: 45px;
border: 1px dotted #000;
}
h1{
color: #7d890d;
font-size: 140%;
font-weight: normal;
margin-left: 35px;
}
h2{
color: #052a6e;
font-weight: normal;
font-size: 125%;
margin-left: 35px;
}
/*********************/
/* Date Properties */
/*********************/
#date {
float: right;
margin: 10px;
}
#day, #ordinal, #year {
float: right;
}
#ordinal {
vertical-align: baseline;
font-size: 0.8em;
position: relative;
top: -0.2em;
}
/* JavaScript Panel Properties */
#panel {
font-size: 0.8em;
width: 100%;
float: left;
margin: 5px;
}
#day0, #day1, #day2, #day3, #day4 {
float: left;
width: 181px;
height: 355px;
border: 1px solid black;
margin: 4px;
text-align: center;
}
td,th {
width: 175px;
height: 35px;
font-size: 1.3em;
}
th {
font-size: 1.5em;
}
#spacerCell {
height: 70px;
}
.tempLow, .tempHigh {
font-size: 2em;
color: blue;
}
.tempHigh {
color: red;
}
.js
var thisDate = new Date();
var day = thisDate.getDate();
var dayNames = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ];
var monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];
var sun = new Forecast( "sunny.png", "Sunny", 17, 31 );
var clouds = new Forecast( "cloudy.png", "Cloudy", 10, 23 );
var showers = new Forecast( "mix.png", "Mix of Sun and Cloud", 12, 20 );
var rain = new Forecast( "rain.png", "Rain", 6, 14 );
var fList = [ sun, clouds, showers, rain ];
var pList = [ "day0", "day1", "day2", "day3", "day4" ];
var low, high;
// Functions
function init()
{
displayDate();
displayForecast();
}
window.onload=init;
function Forecast( image, title, minTemp, maxTemp )
{
this.image=image;
this.title=title;
this.minTemp=minTemp;
this.maxTemp=maxTemp;
}
function randomNumber( min, max )
{
var rand = Math.random() * (max - min + 1) + min;
rand = Math.floor(rand)
return rand;
}
function displayTime( timeZone )
{
var timeE = document.getElementById( timeZone );
var offset, hh, mm, AMorPM;
switch ( timeZone )
{
case "PST":
offset = -7;
break;
case "EST":
offset = -4;
break;
case "CDT":
offset = -5;
break;
default:
timeE.innerHTML += "Error!";
}
thisDate = calcTime( offset );
hh = thisDate.getHours();
mm = thisDate.getMinutes();
if( mm < 10 ){ mm = "0" + mm; }
if( hh > 12 )
{
hh -= 12;
AMorPM = " PM";
}
else
{
AMorPM = " AM";
}
timeE.innerHTML += hh + ":" + mm + " " + AMorPM + " (" + timeZone + ")";
}
// This will return a Date object with the city's current time based on that city's "offset" from the GMT.
function calcTime( offset )
{
var date = new Date();
date.setTime(date.getTime() + date.getTimezoneOffset()*60*1000 + offset*60*60*1000);
return date;
}
//This will return a new Date object for a single forecast
function addDays(myDate,days)
{
return new Date(myDate.getTime() + days*24*60*60*1000);
}
function displayDate()
{
var dayE = document.getElementById("day");
var ordinalE = document.getElementById("ordinal");
var yearE = document.getElementById("year");
// Display the day of the week and the date (month, day)
dayE.innerHTML = dayNames[ thisDate.getDay() ] +", ";
dayE.innerHTML += monthNames[ thisDate.getMonth() ] +" ";
dayE.innerHTML += " " +day;
// Function determining which ending to use for the date and displaying it
switch (day)
{
case 1:
case 21:
case 31:
ordinalE.innerHTML += "st";
break;
case 2:
case 22:
ordinalE.innerHTML += "nd";
break;
case 3:
case 23:
ordinalE.innerHTML += "rd";
break;
default:
ordinalE.innerHTML += "th";
}
// Display the year
yearE.innerHTML = ", " +thisDate.getFullYear();
}
function getDayTitle( i )
{
var dayTitle;
var dayOfWeek = addDays( thisDate, i )
var d = dayOfWeek.getDay();
if( d > 6 )
{
d -= 7;
}
// Function determining which title to use (today, tomorrow, day of the week)
switch ( i )
{
case 0:
dayTitle = "Today";
break;
case 1:
dayTitle = "Tomorrow";
break;
default:
dayTitle = dayNames[d];
}
return dayTitle;
}
function displayForecast()
{
for( i=0; i < pList.length; i++)
{
displayDailyForecast( i );
}
}
function displayDailyForecast( i )
{
var forecastE = document.getElementById( pList[i] );
var forecast = fList[ randomNumber(0,3) ];
var html = "<table>";
if( i == 0)
{
html += "<tr><td id='spacerCell'></td></tr>"
}
html += "<tr><th colspan='2'>" + getDayTitle(i) + "</th></tr>";
html += "<tr><td colspan='2'><img src='images/" + forecast.image + "' width='100' height='100'></td></tr>";
html += "<tr><td colspan='2'>" + forecast.title + "</td></tr>";
getTemp( forecast.minTemp, forecast.maxTemp );
html += "<tr><td class='tempLow'>"+ low +"°C</td>";
html += "<td class='tempHigh'>"+ high +"°C</td></tr>";
forecastE.innerHTML += html;
}
function getTemp( min, max )
{
var t1, t2;
t1 = randomNumber( min, max );
t2 = randomNumber( min, max );
if( t1 < t2 )
{
low = t1;
high = t2;
}
else if( t1 > t2 )
{
low = t2;
high = t1;
}
else // if t1==t2
{
low = t1;
high = t1 + 1;
}
}
Here you go. Use the padding property for padding, you were using a spacercell td for displaying things in the middle, and no a single js file is fine.
EDIT: Fixed a couple things. You were using a .content selector instead of a #content selector in your css. Here is the updated version.
Firstly I want to ask you that do you really need to use table tags for days? I mean cant you use div tags? because in table tag all the inner tags always have relative position.
You can insert div tags inside day0 / day1 etc tags with absolute position and then use
divId.innerHTML = getDayTitle(i)
( all your respective methods ) to set the text instead of generating entire table through js.
Secondly if in future if you change the font etc of your text then also table can create problems because it always uses " fit to contents " type method hence tr size may increase depending on your text size
Use div tags and it will surely work :)
For new browsers use flexbox.
http://www.html5rocks.com/en/tutorials/flexbox/quick/
Related
I'm new to jQuery and in my current project I need to create a list of inputs with following conditions:
When I write something in the first input field another input fields spawns
When I delete the chars and the input field is empty, it will be deleted
In the end all the values will be combined into one string
If possible the list should be in an array (optional)
I'm limited because my knowledge of jQuery isn't good. I managed to create the first condition but I don't know if my solution is any good.
http://jsfiddle.net/kubydpvr/5/
$(document).ready(() => {
let count = 0;
let arr = [createInput(0)];
$(".Fields").append(arr);
function addListField() {
$("#id_" + count).one("input", addListField);
$("#id_" + count).attr({
type: "text"
});
arr.push(createInput(count + 1, "hidden"));
$("#id_" + count).after(createInput(count + 1, "hidden"));
count++;
}
function createInput(id, type = "text") {
return (
"<input type=" + type + ' value = "" id = id_' + id + " ></input>"
);
}
addListField();
});
body {
font-size: 17px;
font-family: "Courier New", Courier, monospace;
background: whitesmoke;
line-height: 1.5em;
}
header {
background: rgb(1, 60, 14);
color: whitesmoke;
padding: 20px;
text-align: center;
border-bottom: 4px rgb(26, 0, 62) solid;
margin-bottom: 10px;
}
.container {
margin: auto;
padding: 10px;
width: 200px;
}
.Fields {
display: flex;
flex-direction: column;
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<header>
<h1>I Learn jQuery.</h1>
<div class="container">
<div class="Fields"></div>
</div>
I think this is what your after
$(document).ready(() => {
let count = 0;
let arr = [createInput(0)];
$(".Fields").append(arr);
function addListField() {
$("#id_" + count).one("input", addListField);
$("#id_" + count).on("change", function() {
let item = parseInt($(this).attr("id").split("_")[1]);
if (!$(this).val().length) {
arr.splice(item, 1)
$(this).remove();
}
})
$("#id_" + count).attr({
type: "text"
});
arr.push(createInput(count + 1, "hidden"));
$("#id_" + count).after(createInput(count + 1, "hidden"));
count++;
}
$("#output").on("click", function() {
let vals = [];
$('[id^=id_]').each(function() {
if ($(this).val() !== "") {
vals.push($(this).val())
}
//vals += $(this).val()
})
console.log(vals)
console.log(arr)
})
function createInput(id, type = "text") {
return (
"<input type=" + type + ' value = "" id = id_' + id + " ></input>"
);
}
addListField();
});
body {
font-size: 17px;
font-family: "Courier New", Courier, monospace;
background: whitesmoke;
line-height: 1.5em;
}
header {
background: rgb(1, 60, 14);
color: whitesmoke;
padding: 20px;
text-align: center;
border-bottom: 4px rgb(26, 0, 62) solid;
margin-bottom: 10px;
}
.container {
margin: auto;
padding: 10px;
width: 200px;
}
.Fields {
display: flex;
flex-direction: column;
}
<!DOCTYPE html>
<html>
<head>
<title>Learn jQuery</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<header>
<h1>I Learn jQuery.</h1>
<div class="container">
<div class="Fields"></div>
</div>
<button id="output">
Output
</button>
</header>
</body>
</html>
I hope this helps
I am currently using a modified version of a JS countdown element for a site coming up. I've been learning a ton of how to use flex grids but haven't done a lot with block/inline-block, etc.
Currently when the countdown hits around 945px, the 4 inline-block boxes stay as 4 columns and end up overflowing to the edge of the screen:
My desired result would be at around 945px, the 4 columns would collapse to 2 side by side, with the text still being under their proper boxes. I was messing around altering the code in "inspect" in chrome and accidentally succeeded in doing this, but the 4 lines of text were still below the element with the boxes rather than in their proper place. Here is what my desired result looks like:
Here is the code:
https://codepen.io/Lancewalker/pen/QxpbZx
$(function (){
function countdown() {
var now = new Date();
var eventDate = new Date(2019, 0, 1);
var currentTime = now.getTime();
var evenTime = eventDate.getTime();
var remTime = evenTime - currentTime;
var sec = Math.floor(remTime / 1000);
var min = Math.floor(sec / 60);
var hur = Math.floor(min / 60);
var day = Math.floor(hur / 24);
hur %= 24;
min %= 60;
sec %= 60;
hur = (hur < 10) ? "0" + hur : hur;
min = (min < 10) ? "0" + min : min;
sec = (sec < 10) ? "0" + sec : sec;
$('.seconds').text(sec);
$('.minutes').text(min);
$('.hours').text(hur);
$('.days').text(day);
setTimeout(countdown, 1000);
}
countdown();
});
body {
background-color: #333;
}
.container {
width: 800px;
height: 350px;
margin: auto;
text-align: center
}
.container h2 {
color: #fff;
font-size: 30px;
font-family: Exo, Arial, Sans-serif;
padding: 50px 0 20px;
font-weight: normal
}
.container .content {
width: 100%;
}
.container .content > div {
display: inline-block;
margin: 35px 10px 0;
width: 120px;
height: 130px;
background: rgb(146, 163, 191, .6);
border-radius: 8px;
border: 1px solid #fff;
color: #fff;
line-height: 138px;
font-family: Exo, arial, sans-serif;
font-size: 55px;
}
.container .title {
width: ;
height: 50px;
position: relative
}
.container .title span {
display: inline-block;
width: 140px;
font-size: 20px;
font-family: 'Exo', arial, sans-serif;
color: #fff;
line-height: 50px;
}
<div class="container">
<h2>Apartments Coming Soon!</h2>
<div class="content">
<div class="days">85</div>
<div class="hours">22</div>
<div class="minutes">33</div>
<div class="seconds">54</div>
</div>
<div class="title">
<span>Days</span>
<span>Hours</span>
<span>Minutes</span>
<span>Seconds</span>
</div>
</div>
You have your .container class width set as a hard 800px value for starters.
.container {
max-width: 800px;
width: 90%;
height: 350px;
margin: auto;
text-align: center
}
Making this simple change will have your timer squares start to collapse underneath. You will have to make some more changes yourself but I would look into media queries and responsive design with %. Anytime you hard code a number such as 800px you will run into issues when you get to a smaller size.
I would also consider refactoring your HTML so that the time squares and titles are together.
<div class="time-square">
<div class="time-square-time">88</div>
<div class="time-square-title">Days</div>
</div>
You will be able to move your HTML around a little more cleanly this way, you are going to run into a few issues matching the title to the time in your current structure
I would suggest restructuring your markup slightly - wrapping the number and the text ('day', 'hour', etc) in the same parent. This will ensure they stay together when content is wrapped.
For the CSS, change width: 800px to max-width - this ensure the content resizes on screens smaller than 800px.
You can then use CSS Grid to layout the boxes and simplify the code.
Codepen
$(function() {
function countdown() {
var now = new Date();
var eventDate = new Date(2019, 0, 1);
var currentTime = now.getTime();
var evenTime = eventDate.getTime();
var remTime = evenTime - currentTime;
var sec = Math.floor(remTime / 1000);
var min = Math.floor(sec / 60);
var hur = Math.floor(min / 60);
var day = Math.floor(hur / 24);
hur %= 24;
min %= 60;
sec %= 60;
hur = (hur < 10) ? "0" + hur : hur;
min = (min < 10) ? "0" + min : min;
sec = (sec < 10) ? "0" + sec : sec;
$('.seconds').text(sec);
$('.minutes').text(min);
$('.hours').text(hur);
$('.days').text(day);
setTimeout(countdown, 1000);
}
countdown();
});
body {
background: #333;
}
.container {
max-width: 800px;
height: 350px;
margin: auto;
text-align: center;
}
.container h2 {
color: #fff;
font-size: 30px;
font-family: Exo, Arial, Sans-serif;
padding: 50px 0 20px;
font-weight: normal;
}
.content {
display: grid;
grid-template-columns: repeat(auto-fit, 120px);
/* use grid gap instead of margin around boxes */
grid-gap: 10px;
justify-content: center;
}
.box>div {
height: 130px;
background: rgb(146, 163, 191, 0.6);
border-radius: 8px;
border: 1px solid #fff;
color: #fff;
font-family: Exo, arial, sans-serif;
font-size: 55px;
margin-bottom: 20px;
/* use flexbox instead of lineheight for vertical centering */
display: flex;
align-items: center;
justify-content: center;
}
.box span {
display: inline-block;
font-size: 20px;
font-family: "Exo", arial, sans-serif;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<h2>Apartments Coming Soon!</h2>
<div class="content">
<div class="box">
<div class="days">85</div>
<span>Days</span>
</div>
<div class="box">
<div class="hours">22</div>
<span>Hours</span>
</div>
<div class="box">
<div class="minutes">33</div>
<span>Minutes</span>
</div>
<div class="box">
<div class="seconds">54</div>
<span>Seconds</span>
</div>
</div>
</div>
Just split into to two parts of div, it will looks fine.
If I misunderstood your question, please let me know.
$(function (){
function countdown() {
var now = new Date();
var eventDate = new Date(2019, 0, 1);
var currentTime = now.getTime();
var evenTime = eventDate.getTime();
var remTime = evenTime - currentTime;
var sec = Math.floor(remTime / 1000);
var min = Math.floor(sec / 60);
var hur = Math.floor(min / 60);
var day = Math.floor(hur / 24);
hur %= 24;
min %= 60;
sec %= 60;
hur = (hur < 10) ? "0" + hur : hur;
min = (min < 10) ? "0" + min : min;
sec = (sec < 10) ? "0" + sec : sec;
$('.seconds').text(sec);
$('.minutes').text(min);
$('.hours').text(hur);
$('.days').text(day);
setTimeout(countdown, 1000);
}
countdown();
});
body {
background-color: #333;
}
.container {
width: 800px;
height: 350px;
margin: auto;
text-align: center
}
.container h2 {
color: #fff;
font-size: 30px;
font-family: Exo, Arial, Sans-serif;
padding: 50px 0 20px;
font-weight: normal
}
.container .content {
width: 100%;
}
.container .content > div {
display: inline-block;
margin: 35px 10px 0;
width: 120px;
height: 130px;
background: rgb(146, 163, 191, .6);
border-radius: 8px;
border: 1px solid #fff;
color: #fff;
line-height: 138px;
font-family: Exo, arial, sans-serif;
font-size: 55px;
}
.container .title {
width: ;
height: 50px;
position: relative
}
.container .title span {
display: inline-block;
width: 140px;
font-size: 20px;
font-family: 'Exo', arial, sans-serif;
color: #fff;
line-height: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<h2>Apartments Coming Soon!</h2>
<div class="content">
<div class="days">85</div>
<div class="hours">22</div>
</div>
<div class="title">
<span>Days</span>
<span>Hours</span>
</div>
<div class="content">
<div class="minutes">33</div>
<div class="seconds">54</div>
</div>
<div class="title">
<span>Minutes</span>
<span>Seconds</span>
</div>
</div>
You can use CSS Media Queries like following:
#media (max-width: 992px) {
.container .content > div, .container .title span {
width: 20%;
}
}
#media (max-width: 768px) {
.container .content > div, .container .title span {
width: 50%;
}
}
$('.btn').on("click", function() {
var text = $(this).text();
$(this).text(text === 'Celsius' ? 'Fahrenheit' : 'Celsius');
changeUnits();
});
function changeUnits(Temp, c) {
if ($('.btn').text() === 'Celsius')
return Math.round((Temp - 273.15)*10)/10 + " °C";
else
return Math.round(((Temp* (9/5)) - 459.67)*10)/10 + " °F";
}
I am trying to use a button on click event to change the temp display, but it doesn't seem to work like this. The function keeps seeing Celsius no matter what. I tried $(this).html too. The text of the button is actually changing, just the function isn't updating. I tried running the change units function inside the the button click even as well and it still doesn't update.
What am I not understanding about this onclick event and how can I get it to work.
JS Code:
var apiKey = "get your own key from http://openweathermap.org";
function changeUnits(Temp, c) {
if ($('.btn').text() === 'Celsius')
return Math.round((Temp - 273.15)*10)/10 + " °C";
else
return Math.round(((Temp* (9/5)) - 459.67)*10)/10 + " °F";
}
$('.btn').on("click", function() {
var text = $(this).text();
$(this).text(text === 'Celsius' ? 'Fahrenheit' : 'Celsius');
changeUnits();
});
$(function() {
var loc;
//api call to get lat and long
$.getJSON('http://ipinfo.io', function(data) {
loc = data.loc.split(",");
//weather API call
$.getJSON('http://api.openweathermap.org/data/2.5/weather?lat=' +
loc[0] + '&lon=' + loc[1] + '&appid=' + apiKey,
function(weather) {
var currentLocation = weather.name;
var currentConditions = weather.weather[0].description;
var currentTemp = changeUnits(weather.main.temp);
var high = changeUnits(weather.main.temp_max);
var low = changeUnits(weather.main.temp_min);
var currentWind = weather.wind.speed;
var currentWdir = weather.wind.deg;
var sunRise = weather.sys.sunrise;
var sunSet = weather.sys.sunset;
var icon = weather.weather[0].icon;
//set HTML elements for weather info
$('#currentLocation').append(currentLocation);
$('#currentTemp').html(currentTemp);
$('#high-low').html('<span id="high">High: ' + high + '</span><br>'
+ '<span id="low">Low: ' + low + '</span>');
$('#currentConditions').html(currentConditions);
var iconSrc = "http://openweathermap.org./img/w/" + icon + ".png";
$('#currentConditions').prepend('Outside the current conditions are <br><img id="weatherImg"src="' + iconSrc + '"><br>');
});
});
});
HTML:
<html>
<head>
<meta name="keywords" content="HTML, CSS, XML, XHTML, JavaScript,width=device-width,initial-scale=1">
<title></title>
</head>
<body>
<div id="header">
<div class="left"><h1 id="currentLocation">Your Current Location is </h1></div>
<div class="navbar"></div>
<div class="right"><i class="fa fa-github bigger_icon"></i></div>
</div>
<div id="container">
<h2 class="text-center content-title" id="currentTemp"></h2>
<div class="content-body text-center">
<p id="high-low"></p>
<button data-text-swap="Fahrenheit" id="unitButton" type="button" class="btn btn-success">Celsius</button>
<p id="currentConditions"></p>
</div>
</div>
</body>
</html>
I have done every change I can think of. console.log(el.text()) in the onclick clearly shows the text changing; but the function for changeUnits never seems to pick it up in the if statement when I run the function again during the onclick.
Looks like you're using html() instead of text(). I assume you're looking for button text instead of html, so try this:
$('.btn').on("click", function() {
$(this).text(function(f, c) {
return c === 'Celsius' ? 'Fahrenheit' : 'Celsius';
});
});
function changeUnits(Temp, c) {
if ($('.btn').text() === 'Celsius'){
return Math.round(Temp - 273.15) + " °C";
}else{
return Math.round((Temp* (9/5)) - 459.67) + " °F";
}
}
you are not calling the function, read comments in code
Also you are not passing any information to the '.btn' in the function passed to the text method.
$('.btn').on("click", function() {
var text = function(f, c) { // where are you getting your f and c parameters?
console.log(f); // should be undefined
console.log(c); // should be undefined
return c === 'Celsius' ? 'Fahrenheit' : 'Celsius';
}();
console.log(text); // should be 'Celsius'
$(this).text(text); // changed from }) to }())
});
function changeUnits(Temp, c) {
if ($('.btn').text() === 'Celsius') // change html() to text() as well
return Math.round(Temp - 273.15) + " °C";
else
return Math.round((Temp* (9/5)) - 459.67) + " °F";
}
Additionaly you should use a ID to associate your button to do this
<input id='thisID'>
// then call it in javascript
$("#thisID")
Toggleing the button
$('.btn').on("click", function() {
var text = $(this).text();
$(this).text(text === 'Celsius' ? 'Fahrenheit' : 'Celsius');
});
Here is what I think is your problem. I didn't get to test it because I need to get the weather API and stuff. By looking at your code, here is what I get.
When the page loads, you are getting weather data from OpenWeatherMap. However, you are not cashing this info in some sort of global variable in order for you to access it later. You have declared all your variables inside the ajax callback and you have no way of accessing them later.
Try to do this:
var currentTemp;
var high;
var low;
$(function() {
var loc;
//api call to get lat and long
$.getJSON('http://ipinfo.io', function(data) {
loc = data.loc.split(",");
//weather API call
$.getJSON('http://api.openweathermap.org/data/2.5/weather?lat=' +
loc[0] + '&lon=' + loc[1] + '&appid=' + apiKey,
function(weather) {
var currentLocation = weather.name;
var currentConditions = weather.weather[0].description;
currentTemp = weather.main.temp;
high = weather.main.temp_max;
low = weather.main.temp_min;
var currentWind = weather.wind.speed;
var currentWdir = weather.wind.deg;
var sunRise = weather.sys.sunrise;
var sunSet = weather.sys.sunset;
var icon = weather.weather[0].icon;
//set HTML elements for weather info
$('#currentLocation').append(currentLocation);
updateDisplay();
$('#currentConditions').html(currentConditions);
var iconSrc = "http://openweathermap.org./img/w/" + icon + ".png";
$('#currentConditions').prepend('Outside the current conditions are <br><img id="weatherImg"src="' + iconSrc + '"><br>');
});
});
});
function changeUnits(Temp) {
if ($('.btn').text() === 'Celsius')
return Math.round((Temp - 273.15)*10)/10 + " °C";
else
return Math.round(((Temp* (9/5)) - 459.67)*10)/10 + " °F";
}
$('.btn').on("click", function() {
var text = $(this).text();
$(this).text(text === 'Celsius' ? 'Fahrenheit' : 'Celsius');
updateDisplay();
});
function updateDisplay(){
$('#currentTemp').html(changeUnits(currentTemp));
$('#high-low').html('<span id="high">High: ' + changeUnits(high) + '</span><br>'
+ '<span id="low">Low: ' + changeUnits(low) + '</span>');
}
I have introduced another function updateDisplay() to actually handle the changing of the displayed temps. As I said, I didn't get to test it. But I am pretty sure it will work.
JS:
var apiKey="get an openweathermap APIKey";
var loc;
var lat;
var long;
var temp;
var high;
var low;
var icon;
//var wind;
//var windDir;
//var windSpd;
//api call to get lat and long
$.getJSON('http://ipinfo.io', function(data) {
loc = data.loc.split(",");
lat = parseFloat(loc[0]);
long = parseFloat(loc[1]);
getWeather(lat, long);
initGmaps(lat, long);
});
//api call to use lat and long to generate a map
window.addEventListener('load', function() {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = '?key=AIzaSyDKgEmSnYmFmbhQVGY8K6NXxV5ym2yZXdc&callback=initMap';
document.body.appendChild(script);
});
function initGmaps(lat, long) {
var map = new GMaps({
div: '#map',
lat: lat,
lng: long,
zoom: 14,
disableDefaultUI: true,
mapTypeId: "satellite",
});
map.addMarker({
lat: lat,
lng: long
});
}
//using weather to get data and plug it into our page
function getWeather(lat, long) {
var api = 'http://api.openweathermap.org/data/2.5/weather?lat=' +
lat + '&lon=' + long + '&appid=' + apiKey;
$.ajax({
url: api,
dataType: 'json',
success: function(data) {
temp = {
f: Math.round(((data.main.temp * 9 / 5) - 459.67) * 100) / 100 + " °F",
c: Math.round(((data.main.temp - 273.15)) * 100) / 100 + " °C"
};
high = {
f: Math.round(((data.main.temp_max * 9 / 5) - 459.67) * 100) / 100 + " °F",
c: Math.round(((data.main.temp_max - 273.15)) * 100) / 100 + " °C"
};
low = {
f: Math.round(((data.main.temp_min * 9 / 5) - 459.67) * 100) / 100 + " °F",
c: Math.round(((data.main.temp_max - 273.15)) * 100) / 100 + " °C"
};
windSpd = {
f: Math.round((data.wind.speed * 2.23694)*10)/10 + " MPH",
c: Math.round((data.wind.speed)*10)/10 + " M/S"
};
var windArr = ["N","NNE","NE","ENE","E","ESE", "SE", "SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"];
var windDir = windArr[Math.floor(((data.wind.deg/22.5)+.5))];
$('#currentLocation').append(data.name);
$('#high').append(" " + high.f);
$('#low').append(" " + low.f);
$('#currentTemp').html(temp.f);
$('#weatherDesc').html(data.weather[0].description);
$('#windDir').html(windDir);
$('#windDir').append('<span id="windSpd">' + windSpd.f + '</span>');
icon = data.weather[0].icon;
var iconSrc = "http://openweathermap.org./img/w/" + icon + ".png";
$('#currentConditions').html('<img id="weatherImg" src="' + iconSrc + '"><br>');
}
});
}
$('#currentTemp').on('click', function() {
var current = $(this).data('nexttemp');
$('#currentTemp').text(temp[current]);
$('#high').html(high[current]);
$('#low').html(low[current]);
$('#windSpd').html(windSpd[current]);
if (current == 'c') {
$(this).data('nexttemp', 'f');
return;
}
$(this).data('nexttemp', 'c');
});
HTML:
<html>
<head>
<meta name="keywords" content="HTML, CSS, XML, XHTML, JavaScript,width=device-width,initial-scale=1">
<title></title>
</head>
<body>
<div id="header">
<div class="left"></div>
<div class="navbar"><h4>Free Code Camp Weather App</h4></div>
<div class="right"><i class="fa fa-github bigger_icon"></i></div>
</div>
<div id="container">
<div class="col-lg-4" id="map"></div>
<div class="col-lg-4">
<h1 id="currentLocation">Your Current Location is </h1>
</div>
<h2 class="center-text content-title" id="currentTemp"></h2>
<h3 id="caption">Click temperature to change Units</h3>
<div class="center-text">
<p class="oneLine" id="labels">High: <span id="high"></span></p>
<p class="oneLine" id="labels">Low: <span id="low"></span></p>
</div>
<p class="center-text" id="currentConditions"></p>
<p class="center-text" id="weatherDesc"></p>
<div class="windCompass col-lg-4">
<div class="compass">
<div class="direction">
<p id="windDir"></p>
</div>
<div class="arrow ne"></div>
</div>
</div>
</div>
</body>
</html>
CSS:
#import url(http://fonts.googleapis.com/css?family=Dosis:200,400,500,600);
body {
background: url(http://eskipaper.com/images/pixel-backgrounds-1.jpg);
background-size: auto;
background-repeat: no-repeat;
font-family: Ranga, cursive;
}
h4 {
margin-top: 7px;
}
h1 {
margin-left: -7px;
font-size: 1.05em;
color: white;
}
#header {
background: #2980b9;
color: white;
padding: 0 5px;
display: inline-block;
width: 100%;
margin: 0;
box-shadow: 0 2px 5px #555555;
}
#header .left {
display: inline-block;
width: auto;
float: left;
margin-top: 7px;
margin-left: 7px;
}
#header .navbar {
display: inline-block;
width: 60%;
}
#header .right {
display: inline-block;
width: auto;
text-align: right;
float: right;
margin-top: 2px;
margin-right: 7px;
vertical-align: bottom;
}
.bigger_icon {
margin-top: 10px;
font-size: 2em;
color: white;
}
#map {
height: 200px;
width: 200px;
border-radius: 5%;
margin-top: 20px;
}
#container {
background: rgba(66, 66, 66, 0.6);
display: block;
position: relative;
width: 40%;
margin: 24px auto;
min-height: 300px;
padding: 16px;
border-radius: 4px;
}
#container .center-text {
text-align: center;
}
h2 {
color: white;
font-family: Ranga, cursive;
font-size: 2.5em;
font-weight: bold;
margin-top: -230px;
}
#caption {
font-size: 17px;
text-align: center;
color: pink;
}
#labels {
color: darkGrey;
font-size: 1.5em;
}
.oneLine {
color: darkGrey;
font-size: 1.5em;
text-align: center;
display: inline;
padding: 5px;
}
#high {
text-align: center;
color: orange;
}
#low {
text-align: center;
color: blue;
}
#currentConditions {
text-align: center;
color: black;
}
#weatherDesc {
margin-top: -25px;
color: white;
}
.windCompass {
margin-left: 75%;
margin-top: -20%;
}
.compass {
display: block;
width: 120px;
height: 120px;
border-radius: 100%;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.85);
position: relative;
font-family: 'Dosis';
color: #555;
text-shadow: 1px 1px 1px white;
}
.compass:before {
font-weight: bold;
position: absolute;
text-align: center;
width: 100%;
content: "N";
font-size: 14px;
top: -2px;
}
.compass .direction {
height: 100%;
width: 100%;
display: block;
background: #f2f6f5;
background: -moz-linear-gradient(top, #f2f6f5 30%, #cbd5d6 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f2f6f5), color-stop(100%, #cbd5d6));
background: -webkit-linear-gradient(top, #f2f6f5 0%, #cbd5d6 100%);
background: o-linear-gradient(top, #f2f6f5 0%, #cbd5d6 100%);
border-radius: 100%;
}
.compass .direction p {
text-align: center;
margin: 0;
padding: 0;
position: absolute;
top: 50%;
left: 0;
width: 100%;
height: 100%;
line-height: 80px;
display: block;
margin-top: -35%;
font-size: 28px;
font-weight: bold;
}
.compass .direction p span {
display: block;
line-height: normal;
margin-top: -10%;
font-size: 17px;
text-transform: uppercase;
font-weight: normal;
font-family: Ranga, cursive;
}
.compass .arrow {
width: 100%;
height: 100%;
display: block;
position: absolute;
top: 0;
}
.compass .arrow:after {
content: "";
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 10px solid red;
position: absolute;
top: -6px;
left: 50%;
margin-left: -5px;
z-index: 99;
}
.compass .arrow.nne {
transform: rotate(22.5deg);
}
.compass .arrow.ne {
transform: rotate(45deg);
}
.compass .arrow.ene {
transform: rotate(67.5deg);
}
.compass .arrow.e {
transform: rotate(90deg);
}
.compass .arrow.ese {
transform: rotate(112.5deg);
}
.compass .arrow.se {
transform: rotate(135deg);
}
.compass .arrow.sse {
transform: rotate(157.5deg);
}
.compass .arrow.s {
transform: rotate(180deg);
}
.compass .arrow.ssw {
transform: rotate(202.5deg);
}
.compass .arrow.sw {
transform: rotate(-135deg);
}
.compass .arrow.wsw {
transform: rotate(-114.5deg);
}
.compass .arrow.w {
transform: rotate(-90deg);
}
.compass .arrow.wnw {
transform: rotate(-69.5deg);
}
.compass .arrow.nw {
transform: rotate(-45deg);
}
.compass .arrow.nnw {
transform: rotate(-24.5deg);
}
I ended up finding some Ajax and working with it to do what I expected the button to do. While not a button, it does what is intended. I also worked in changing the high, low, and wind speed to also change with the unit change.
I appreciate the help that everyone offered.
feel free to offer suggestions on the code as well for fixing the css for the compass gradient and making the stupid thing more responsive if you'd like. (The Map is not doing the responsive thing.
Your script probably gets loaded before the DOM is ready.
What you want to do here is one of a few options:
1. Load the JS script tag at the end of the body.
2. Wrap your $('.btn').on(...) function with document.on('ready') event, so this code will only be triggered when the DOM is ready.
I have a simple html page for a Christmas countdown. The countdown functions fine and running ok, but the problem is that i am trying to call a video at specific times of the day.
So I want the timer to continue running until say on the hour then i want my 3 minute video to play, once the video has finished i would like it to return to my countdown timer.
I have tried to do the timer for the video nothing seems to happen and the timer continues to play.
Here is all my code...
HTML
<html>
<head>
<title>Xmas Countdown</title>
<link href="css/style.css" rel="stylesheet" type="text/css" />
<script src="js/countdown.js"></script>
<script src="js/video.js"></script>
</head>
<body onload="startTime()">
<div id="header">
<h1>Santa will be here in...</h1>
</div>
<div id="del-countdown">
<div id="clock"></div>
<div id="units">
<span>Days</span>
<span>Hours</span>
<span>Minutes</span>
<span>Seconds</span>
</div>
</div>
<div id="footer">
<h2>Merry Christmas</h2>
</div>
</body>
</html>
VIDEO.JS
function startTime() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
var video = document.createElement('video');
video.src = '/media/santa.mp4';
video.autoPlay = true;
if(m=>00) {
document.getElementById('video').src
}
var t = setTimeout(startTime, 500);
}
window.onload = ('startTime()');
};
COUNTDOWN.JS
function updateTimer(deadline){
var time = deadline - new Date();
return {
'days': Math.floor( time/(1000*60*60*24) ),
'hours': Math.floor( (time/(1000*60*60)) % 24 ),
'minutes': Math.floor( (time/1000/60) % 60 ),
'seconds': Math.floor( (time/1000) % 60 ),
'total' : time
};
}
function startTimer(id, deadline){
var timerInterval = setInterval(function(){
var clock = document.getElementById(id);
var timer = updateTimer(deadline);
clock.innerHTML = '<span>' + timer.days + '</span>'
+ '<span>' + timer.hours + '</span>'
+ '<span>' + timer.minutes + '</span>'
+ '<span>' + timer.seconds + '</span>';
//check for end of timer
if(timer.total < 1){
clearInterval(timerInterval);
clock.innerHTML = '<span>0</span><span>0</span><span>0</span><span>0</span>';
}
}, 1000);
}
window.onload = function(){
var deadline = new Date("December 25, 2016 00:00:00");
startTimer("clock", deadline);
};
CSS
#font-face {
font-family: Polo;
src: url(fonts/Polo.ttf);
}
body{
position: relative;
background: #f21c0a;
font-family: Polo;
max-height: 100%;
}
h1{
color: #fff;
text-align: center;
font-size: 100px;
letter-spacing: 8px;
}
h2{
color: #fff;
text-align: center;
font-size: 45px;
letter-spacing: 8px;
}
#header{
width: 100%;
margin: 5% auto;
}
#footer{
width: 100%;
margin-top: 20% auto;
}
#del-countdown{
width: 100%;
margin: 10% auto;
}
#clock span{
float: left;
text-align: center;
font-size: 150px;
margin: 0 2.5%;
color: #fff;
padding: 50px;
width: 20%;
border-radius: 20px;
box-sizing: border-box;
}
#clock span:nth-child(1){
background: #fa3221;
}
#clock span:nth-child(2){
background: #fa3221;
}
#clock span:nth-child(3){
background: #fa3221;
}
#clock span:nth-child(4){
background: #fa3221;
color: #b90b01;
}
#clock:after{
content: "";
display: block;
clear: both;
}
#units span{
float: left;
width: 25%;
text-align: center;
margin-top: 15px;
color: #fff;
text-transform: uppercase;
font-size: 30px;
letter-spacing: 1px;
}
The app is fully functioning when I open the html file in my browser, but when I try and open it on localhost:3000 it only loads the html and doesn't pick up the css or javascript.
HTML:
<html>
<head>
<link href="./main.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="del-countdown">
<h1>THE SINGULARITY IS NEAR</h1>
<div id="clock"></div>
<div id="units">
<span>Years</span>
<span>Days</span>
<span>Hours</span>
<span>Minutes</span>
<span>Seconds</span>
</div>
</div>
<script src="../index.js"></script>
</body>
</html>
CSS:
body{
background: #282e3a;
font-family: tahoma;
}
h1{
color: #fff;
text-align: center;
font-size: 74px;
letter-spacing: 10px;
margin-bottom: 5px;
}
h3{
color: #fff;
text-align: center;
font-size: 36px;
letter-spacing: 5px;
margin-top: 5px;
}
#del-countdown{
width: 850px;
margin: 15% auto;
}
#clock span{
float: left;
text-align: center;
font-size: 84px;
margin: 0 2%;
color: #fff;
padding: 20px;
width: 16%;
border-radius: 20px;
box-sizing: border-box;
}
#clock span:nth-child(1){
background: #696868;
}
#clock span:nth-child(2){
background: #7D7C7C;
}
#clock span:nth-child(3){
background: #9E9E9E;
}
#clock span:nth-child(4){
background: #C4C4C4;
}
#clock span:nth-child(5){
background: #D9D7D7;
}
#clock:after{
content: "";
display: block;
clear: both;
}
#units span{
float: left;
width: 20%;
text-align: center;
margin-top: 30px;
color: #ddd;
text-transform: uppercase;
font-size: 13px;
letter-spacing: 2px;
text-shadow: 1px 1px 1px rgba(10,10,10, 0.7);
}
span.turn{
animation: turn 0.7s ease forwards;
}
#keyframes turn{
0%{transform: rotateX(0deg)}
100%{transform: rotateX(360deg)}
}
Index.js:
function updateTimer(deadline){
var time = deadline - new Date();
return {
'years': Math.floor( time/(1000*60*60*24*365) ),
'days': Math.floor( time/(1000*60*60*24) % 365 ),
'hours': Math.floor( (time/(1000*60*60)) % 24 ),
'minutes': Math.floor( (time/1000/60) % 60 ),
'seconds': Math.floor( (time/1000) % 60 ),
'total' : time
};
}
function animateClock(span){
span.className = "turn";
setTimeout(function(){
span.className = "";
},700);
}
function startTimer(id, deadline){
var timerInterval = setInterval(function(){
var clock = document.getElementById(id);
var timer = updateTimer(deadline);
clock.innerHTML = '<span>' + timer.years + '</span>'
+ '<span>' + timer.days + '</span>'
+ '<span>' + timer.hours + '</span>'
+ '<span>' + timer.minutes + '</span>'
+ '<span>' + timer.seconds + '</span>';
//animations
var spans = clock.getElementsByTagName("span");
animateClock(spans[4]);
if(timer.seconds == 59) animateClock(spans[3]);
if(timer.minutes == 59 && timer.seconds == 59) animateClock(spans[2]);
if(timer.hours == 23 && timer.minutes == 59 && timer.seconds == 59) animateClock(spans[1]);
if(timer.days == 364 && timer.hours == 23 && timer.minutes == 59 && timer.seconds == 59) animateClock(spans[0]);
//check for end of timer
if(timer.total < 1){
clearInterval(timerInterval);
clock.innerHTML = '<span>0</span><span>0</span><span>0</span><span>0</span><span>0</span>';
}
}, 1000);
}
window.onload = function(){
var deadline = new Date("January 01, 2045 00:00:01");
startTimer("clock", deadline);
};
Server.js
var http = require('http')
var fs = require('fs')
var path = require('path')
//404 response
function send404Response(res) {
res.writeHead(404, {"Content-Type": "text/plain"})
res.write("Error 404: Page not found!")
res.end()
}
//Handle user request
function onRequest(req, res) {
if(req.method == 'GET' && req.url == '/') {
res.writeHead(200, {"Content-Type": "text/html"})
fs.createReadStream("./public/index.html").pipe(res)
}
else{
send404Response(res)
}
}
http.createServer(onRequest).listen(3000)
console.log("Server is now running...");
put the js and css file in a folder named pubilc. And call app.use('/public',express.static(__dirname + '/public'));
Now add css and js src="/public/js"