Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Adam Evans
Adam Evans
6,975 Points

Best Way to Proceed: Need Advice on Calendar JavaScript Integration

CodePen: http://codepen.io/Alevans/pen/tdGgm

www.adamevansdesigns.com

So I took the website I made in the first part of the Web Design track and have slowly been changing it and making it into a site for some training I am doing for a half marathon. The calendar is very basic and I have done a bit of JavaScript and jQuery to show a countdown until the day of the race. The idea is to show the calendar for the month and the mileage I ran. Eventually, I will add screenshots from Strava for each run showing the stats.

If you look at my HTML/CSS, I currently have a bunch of empty divs for the calendar with the date in the upper left hand corner. Towards the end of the July, I have added some paragraphs with the mileage I ran.

Now, I could just manually add each run I do into the HTML but that seems really easy and kind of boring. I wanted to work in some JavaScript. That way, if I stored my runs in let's say, an Array or Object, I could access it and also display stats like total mileage, weekly mileage, hours run, etc.

SO, I've thought about this for hours and can't come to a definite conclusion. My idea was to create an array ( I read to use Arrays if the key/value pair is integers) and have each day correspond with mileage ran: The format being [[ Day of the Month, Mileage Ran ], [ Day of the Month, Mileage Ran ]] etc. I would have to manually assign the values as I do the runs, but it would at least be stored in the array.

The problem is how to display this. I used the replaceWith(); jQuery function to add the countdown in the top left (which doesn't work in CodePen but works live). I was thinking I could use this function, and replace divs in the HTML with the array value. What I can't figure out is how to go through the list of divs, since, say for July, all 35 divs have the same class name. I understand loops and functions in JS but I don't know how to progress through the DOM and change each one, rather than replace ALL of class="cal" with the same number, or assign each day a different class.

Obviously, this is more complicated than just plugging in the <p>s but I want a challenge. I am not looking for a complete coded answer, just some direction in terms of what functions to look at (nextChild()?) or what I can do to progress down the DOM and change each div individually (if possible). I hope that was all clear enough!

Thanks!

4 Answers

Aaron Graham
Aaron Graham
18,033 Points

You can refactor your function to store the current day in a variable and use that variable any time you need to reference the day.

$("div.tabs > div.tab > div.august > div ").each(function () {
  var day = $(this).text();
  if(august.hasOwnProperty(day)) {
    $(this).append('<p><a href="img/aug' + day + '.png">' + august[day] + ' miles</a></p>');
  }
})

I updated the codepen we were using earlier to reflect this change: http://codepen.io/aarcg/pen/DKEqd

Aaron Graham
Aaron Graham
18,033 Points

You might be best off saving your information in an object like this:

var data = {3: '3 miles',
            5: '4 miles'
};

That way you can use jQuery's each function to iterate over the cal divs, get the associated text value, see if the data object has that property, and append the miles if it does. Here is a fork of your codepen with a working example. http://codepen.io/anon/pen/Lfznp This was pretty quick and dirty so it would probably need to be cleaned up a bit. There are probably several different ways to do this. Hopefully this gives you some ideas.

Adam Evans
Adam Evans
6,975 Points

I definitely like this. The problem is if the mileage for the runs is stored in a string, I cannot play with the data to do other calculations unless I separate out the integer from the string. I altered your code a bit - what do you think about this:

var data = {3: 3,
            8: 3,
            5: 4,
            11: 6
           };


$('div.cal').each(function () {
  if(data.hasOwnProperty($(this).text())) {
    $(this).append('<p>' + data[$(this).text()] + ' miles</p>');
  }
})


var totalRun = 0;
for (var i in data){
  totalRun += data[i];
}

http://codepen.io/Alevans/pen/uijFe

Aaron Graham
Aaron Graham
18,033 Points

That definitely works. You can also use parseInt() if you keep the milage as a string and want to use it to do some math:

parseInt('3 miles') //returns 3 as a 'number'

The way you have it is probably better. It seems more correct to store a number in the object if you plan to use it in any calculations.

Adam Evans
Adam Evans
6,975 Points

So I am going to reopen this and see what happens:

Calendar is working fine but now I am looking to add a photo to each of my links through the jQuery method. The photo for the run will be named 'aug1', 'aug2' so the number corresponds with the day of the run and thus with the key value in the object storing the data. How can I access the key and tack it onto the photo name? I can get it to work with a static number added on but I cannot seem to get the key value.

var august = {1: 6,
              5: 3,
              6: 4,
              7: 3,
              9: 7,
           };

var augustKeys = Object.keys(august);

var augustTotalDist = 0;
for (var i in august){
  augustTotalDist += august[i];
}

Object.size = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

var augustTotalRun = Object.size(august);
var augustTotalTime = augustTotalDist * 10;

$(document).ready(function() {
$("div.tabs > div.tab > div.august > div ").each(function () {
  if(august.hasOwnProperty($(this).text())) {
    $(this).append('<p><a href="img/aug' + SomeWayToAddKeyValueOfCurrentData + '.png">' + august[$(this).text()] + ' miles</a></p>');
  }
})})

The var augustKeys stores the values of the keys and I thought accessing that would be easy but I can't seem to get it work..

Thanks!