Dynamic Filterable Life Plan / Timeline (PHP, jQuery, CSS)
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 -51 daysMy 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 95 daysThis 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 314 daysUnless we decide to stay in Germany or move elsewheretravel
-
2013.07.15 Accomplish a Free-Standing Backflip in 3 years, 126 daysI’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 7 years, 174 daysContact me if you want to be one of my pre-publication reviewerscreative
-
2026.07.22 Engineering Degree from MIT in 16 years, 132 daysOh, yes, I will be going back to school. Probably many times in my life.education
-
2044.11.17 Undergo First Major Rejuvination Treatments in 34 years, 250 daysCertainly 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; } |

