Dynamic Filterable Life Plan / Timeline (PHP, jQuery, CSS)

November 6th, 2009 | Categories: CSS, JavaScript, jQuery, PHP, Tutorials | Tags: , , , , , , , , ,

I just created my life plan (or the start of one anyway--I'll be editing this thing for a while) and I figured I'd share with you the code used to make it.
My live updated version is on my Portfolio: The Future as I See It.

Demo

  • 2010.01.20 Move to Magdeburg, Deutschland in -2711 days
    My family will be moving to Magdeburg to experience living in Germany and to strenghten our deutsche Sprachfähigkeiten.
    travel

  • 2010.06.15 Produce an iPhone App in -2565 days
    This might get done before I move to Magdeburg but this is my personal deadline for a v1.0 release.
    work

  • 2011.01.20 Move Back to Seattle, WA USA in -2346 days
    Unless we decide to stay in Germany or move elsewhere
    travel

  • 2013.07.15 Accomplish a Free-Standing Backflip in -1440 days
    I've done it on a trampoline and with spotters but never alone without aid. This is a life-long goal.
    fitness

  • 2017.09.01 Publish First Novel in 68 days
    Contact me if you want to be one of my pre-publication reviewers
    creative

  • 2026.07.22 Engineering Degree from MIT in 9 years, 27 days
    Oh, yes, I will be going back to school. Probably many times in my life.
    education

  • 2044.11.17 Undergo First Major Rejuvination Treatments in 27 years, 145 days
    Certainly there will be many improvements to personal health management before this date, but this is the anticipated date of my first major operation (or likely, full system nanobot integration)
    fitness

The PHP/HTML

Of course, you will need to make sure you include jQuery. I recommend using the Google Hosted Ajax Library rather than hosting it yourself. There are many good reasons to do this (blog post soon to come).
Just place this either in your HTML head or just before your closing body tag:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

I've used PHPDoc blocks to supply inline documentation throughout the code. Post a comment with any questions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<?php 
$pageName = 'plan';
$pageTitle = 'The Future as I See It';
include('header.php'); 
 
/**
 * get the years and days until a date
 * this function is a bit of a hack until my server supports PHP 5.3.0
 * which has date_diff, alias of DateTime::diff (http://www.php.net/manual/en/datetime.diff.php)
 */
function getUntil($year,$month,$day){
	$year = intval($year);
	$maxYear = 2035;
	$addtime = 0;
	if($year > $maxYear){
		$diffYears = $year - $maxYear;
		$year = $maxYear;
		$addtime = $diffYears * 31536000; // years of seconds
	}
 
	// count leap years
	$numYears = $year - date('Y');
	$leaps = floor($numYears/4);
	$addtime -= $leaps * 86400; // subtract these excess days (to get accurate year count)
 
	$date = mktime(0,0,0,$month,$day,$year) + $addtime;
	$now = time();
	$days = ceil(($date - $now)/86400);
	if($days < 365){
		return 'in '.$days .' day'.($days==1?'':'s');
	}else{
		$years = floor($days/365);
		$days = $days%365;
		return 'in '.$years.' year'.($years==1?'':'s').', '.$days.' day'.($days==1?'':'s');
	}
}
$events = array(
	array(
		'yyyy'=>'2010','mm'=>'01','dd'=>'20',
		'name'=>'Move to Magdeburg, Deutschland',
		'info'=>'My family will be moving to Magdeburg to experience living in Germany and to strenghten our deutsche Sprachfähigkeiten.',
		'type'=>'travel'
	),
	array(
		'yyyy'=>'2010','mm'=>'06','dd'=>'15',
		'name'=>'Produce an iPhone App',
		'info'=>'This might get done before I move to Magdeburg but this is my personal deadline for a v1.0 release.',
		'type'=>'work'
	),
	array(
		'yyyy'=>'2013','mm'=>'07','dd'=>'15',
		'name'=>'Accomplish a Free-Standing Backflip',
		'info'=>'I\'ve done it on a trampoline and with spotters but never alone without aid. This is a life-long goal.',
		'type'=>'fitness'
	),
	array(
		'yyyy'=>'2017','mm'=>'09','dd'=>'01',
		'name'=>'Publish First Novel',
		'info'=>'Contact me if you want to be one of my pre-publication reviewers',
		'type'=>'creative'
	),
	array(
		'yyyy'=>'2021','mm'=>'07','dd'=>'22',
		'name'=>'Give First TED Talk',
		'info'=>'On what topic? Web, security, social media, nano-technology, engineering, the future, productivity in an age of overabundance? I\'m not sure yet--but it will be awesome.',
		'url'=>'http://ted.com',
		'type'=>'social'
	),
	array(
		'yyyy'=>'2026','mm'=>'07','dd'=>'22',
		'name'=>'Engineering Degree from MIT',
		'info'=>'Oh, yes, I will be going back to school. Probably many times in my life.',
		'type'=>'education'
	),
	array(
		'yyyy'=>'2044','mm'=>'11','dd'=>'17',
		'name'=>'Undergo First Major Rejuvination Treatments',
		'info'=>'Certainly there will be many improvements to personal health management before this date, but this is the anticipated date of my first major operation (or likely, full system nanobot integration)',
		'type'=>'fitness'
	),
	array(
		'yyyy'=>'2079','mm'=>'11','dd'=>'05',
		'name'=>'Engage Dyson Sphere',
		'url'=>'http://en.wikipedia.org/wiki/Dyson_sphere',
		'info'=>'If not on the team that deploys it, I will at least be celebrating the event :)',
		'type'=>'social'
	)
);
?>
 
<h1><?=$pageTitle?></h1>
<div id="pageFilter">
<a href="javascript:pageFilter('all')" class="active all" title="Show All">show all</a><?php
$types = array();
foreach($events as $event){
	if(empty($types[$event['type']])) $types[$event['type']] = 1;
	else	$types[$event['type']]++;
}
ksort($types);
 
foreach($types as $key=>$val){
	echo '<a href="javascript:pageFilter(\''.$key.'\')" class="'.$key.'" title="Show '.ucfirst($key).'">'.$key.' ('.$val.')</a>';
}
?>
</div>
<ul class="timeline">
<?php
foreach($events as $event){
	?>
    <li class="<?=$event['type']?>">
    	<div class="head">
            <span class="date"><?=$event['yyyy'].'.'.$event['mm'].'.'.$event['dd']?></span>
            <span class="name"><?=$event['name']?></span>
			<?
            if(!empty($event['url'])) echo '[<span class="url"><a href="'.$event['url'].'">more info</a></span>]';
            ?>
            <span class="until"><?=getUntil($event['yyyy'],$event['mm'],$event['dd'])?></span>
        </div>
        <div class="body">
            <div class="info"><?=$event['info']?></div>
            <div class="type"><?=$event['type']?></div>
        </div>
    </li>
    <?
}
?>
</ul>
 
<script type="text/javascript">
function pageFilter(type){
	$('#pageFilter a').removeClass('active');
	$('#pageFilter .'+type).addClass('active');
	if(type=='all'){
		$('.timeline li').slideDown();
	}else{
		$('.timeline li').slideUp();
		$('li.'+type).slideDown();
	}
}
$('.type').bind('click',function(){
	pageFilter($(this).html());					 
});
</script>
 
<?php include('footer.php'); ?>

The CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#pageFilter {
	font-size:.8em;
	text-align:right;
	margin-top:10px;
}
#pageFilter a{
	border:1px solid #dde;
	padding:3px 5px;
	margin-left:5px;
}
.timeline {
	list-style:none;
	font-size:.8em;
}
.timeline li{
	margin-top:10px;
	border:1px solid #9cf;
}
.timeline .head {
	background-color:#def;
	padding:3px 5px;
}
.timeline .body {
	padding:10px;
	position:relative;
}
.timeline .date{
	color:#036;
	font-weight:bold;
	margin-right:10px;
}
.timeline .name{
	color:#666;
}
.timeline .until{
	float:right;
}
.timeline .info{
	padding-bottom:15px;
}
.timeline .type{
	position:absolute;
	bottom:0;
	right:0;
	border:1px solid #dde;
	background-color:#ffe;
	padding:3px 3px 3px 5px;
	cursor:pointer;
}
a.all, .timeline .all .type{
	background-color:#FFFFFF;
}
a.creative, .timeline .creative .type{
	background-color:#F0FFFD;
}
a.education, .timeline .education .type{
	background-color:#EEF4FF;
}
a.fitness, .timeline .fitness .type{
	background-color:#F2EEFE;
}
a.social, .timeline .social .type{
	background-color:#FDF5F5;
}
a.travel, .timeline .travel .type{
	background-color:#FFFDED;
}
a.work, .timeline .work .type{
	background-color:#F3FFEB;
}
No comments yet.
You must be logged in to post a comment.