Tuesday, January 5, 2010

Advanced Event Timeline With PHP, CSS & jQuery

Step 1 – XHTML

First, be sure to grab the example files from the button above, so that you can easily follow what is going on.

The first step of this tut is to create the XHTML structure, as seen in demo.php.

demo.php



01.<div id="timelineLimiter"> <!-- Hides the overflowing timelineScroll div -->
02.<div id="timelineScroll"> <!-- Contains the timeline and expands to fit -->
03.
04.<!-- PHP code that generates the event list -->
05.
06.<div class="clear"></div>
07.</div>
08.
09.<div id="scroll"> <!-- The year time line -->
10.<div id="centered"> <!-- Sized by jQuery to fit all the years -->
11.<div id="highlight"></div> <!-- The light blue highlight shown behind the years -->
12.<?php echo $scrollPoints ?> <!-- This PHP variable holds the years that have events -->
13.<div class="clear"></div>
14.
15.</div>
16.</div>
17.
18.<div id="slider"> <!-- The slider container -->
19.<div id="bar"> <!-- The bar that can be dragged -->
20.<div id="barLeft"></div> <!-- Left arrow of the bar -->
21.<div id="barRight"></div> <!-- Right arrow, both are styled with CSS -->
22.</div>
23.</div>
24.
25.</div>

I have omitted some of the PHP code that generates the events so we can take a better look at the markup (we will get back to it in the next step).

Te main idea is that we have two divs – timelineLimiter and timelineScroll positioned inside it. The former takes the width of the screen, and the latter is expanded to fit all the event sections that are inserted inside it. This way only a part of the larger inner div is visible and the rest can be scrolled to the left and right by a jQuery slider we will be making in step 4.

Now lets take a look at the PHP back-end.

Advanced Event Timeline With PHP MySQL CSS jQuery

Advanced Event Timeline With PHP MySQL CSS jQuery


Step 2 – PHP

PHP selects all the events in the database and groups the events by year in the $dates array. It later loops through it and outputs all the events as

  • elements inside of unordered lists which belong to each of the event years.

    demo.php





  • 01.// We first select all the events from the database ordered by date:
    02.
    03.$dates = array();
    04.$res = mysql_query("SELECT * FROM timeline ORDER BY date_event ASC");
    05.
    06.while($row=mysql_fetch_assoc($res))
    07.{
    08. // Store the events in an array, grouped by years:
    09. $dates[date('Y',strtotime($row['date_event']))][] = $row;
    10.}
    11.
    12.$colors = array('green','blue','chreme');
    13.$scrollPoints = '';
    14.
    15.$i=0;
    16.foreach($dates as $year=>$array)
    17.{
    18. // Loop through the years:
    19.
    20. echo '
    21. <div class="event">
    22. <div class="eventHeading '.$colors[$i++%3].'">'.$year.'</div>
    23. <ul class="eventList">';
    24.
    25. foreach($array as $event)
    26. {
    27. // Loop through the events in the current year:
    28.
    29. echo '<li class="'.$event['type'].'">
    30. <span class="icon" title="'.ucfirst($event['type']).'"></span>
    31. '.htmlspecialchars($event['title']).'
    32.
    33. <div class="content">
    34. <div class="body">'.($event['type']=='image'?'<div style="text-align:center"><img src="'.$event['body'].'" alt="Image" /></div>':nl2br($event['body'])).'</div>
    35. <div class="title">'.htmlspecialchars($event['title']).'</div>
    36. <div class="date">'.date("F j, Y",strtotime($event['date_event'])).'</div>
    37. </div>
    38. </li>';
    39. }
    40.
    41. echo '</ul></div>';
    42.
    43. // Generate a list of years for the time line scroll bar:
    44. $scrollPoints.='<div class="scrollPoints">'.$year.'</div>';
    45.
    46.}

    Thus the complete markup for the page is generated. Now we are ready to apply some styles.

    The Event Sections

    The Event Sections


    Step 3 – CSS

    After we’ve inserted the CSS stylesheet to the head section of the document, we can start laying down the rules. Only the more interesting ones are included here. You can view the rest in styles.css.

    styles.css




    01..event{
    02. /* Contains the section title and list with events */
    03. float:left;
    04. padding:4px;
    05. text-align:left;
    06. width:300px;
    07. margin:0 5px 50px;
    08.}
    09.
    10..eventList li{
    11. /* The individual events */
    12. background:#F4F4F4;
    13. border:1px solid #EEEEEE;
    14. list-style:none;
    15. margin:5px;
    16. padding:4px 7px;
    17.
    18. /* CSS3 rounded corners */
    19. -moz-border-radius:4px;
    20. -webkit-border-radius:4px;
    21. border-radius:4px;
    22.}
    23.
    24..eventList li:hover{
    25. /* The hover state: */
    26. cursor:pointer;
    27. background:#E6F8FF;
    28. border:1px solid #D4E6EE;
    29. color:#548DA5;
    30.}
    31.
    32.li span{
    33. /* The event icon */
    34. display:block;
    35. float:left;
    36. height:16px;
    37. margin-right:5px;
    38. width:16px;
    39.}
    40.
    41./* Individual background images for each type of event: */
    42.
    43.li.news span.icon { background:url(img/icons/newspaper.png) no-repeat; }
    44.li.image span.icon { background:url(img/icons/camera.png) no-repeat; }
    45.li.milestone span.icon { background:url(img/icons/chart.png) no-repeat; }
    46.
    47.#timelineLimiter{
    48. /* Hides the overflowing timeline */
    49. width:100%;
    50. overflow:hidden;
    51. padding-top:10px;
    52. margin:40px 0;
    53.}
    54.
    55.#scroll{
    56. /* The small timeline below the main one. Hidden here and shown by jQuery if JS is enabled: */
    57. display:none;
    58. height:30px;
    59.
    60. background:#F5F5F5;
    61. border:1px solid #EEEEEE;
    62. color:#999999;
    63.}
    64.
    65..scrollPoints{
    66. /* The individual years */
    67. float:left;
    68. font-size:1.4em;
    69. padding:4px 10px;
    70. text-align:center;
    71. width:100px;
    72.
    73. position:relative;
    74. z-index:10;
    75.}

    Here the .event class styles the event years sections (these are the divs that group events that have happened in the same year).

    Near the middle of the code you can see that we’ve used some CSS3 rounded corners which work in the majority of browsers (not supported by IE and Opera).

    We also define individual background images for each of the event types – image, news or milestone.

    Step 4 – jQuery

    The last step is to insert a layer of interactivity into the browser. We will be doing this with the help of the jQuery JavaScript library, included in the head section of demo.php.

    I’ve split the code below in two parts so they are more comprehensible.


    script.js – Part 1



    01.$(document).ready(function(){
    02.
    03. /* This code is executed after the DOM has been completely loaded */
    04.
    05. /* The number of event sections / years with events */
    06.
    07. var tot=$('.event').length;
    08.
    09. $('.eventList li').click(function(e){
    10.
    11. showWindow('<div>'+$(this).find('div.content').html()+'</div>');
    12. });
    13.
    14. /* Each event section is 320 px wide */
    15. var timelineWidth = 320*tot;
    16.
    17. var screenWidth = $(document).width();
    18.
    19. $('#timelineScroll').width(timelineWidth);
    20.
    21. /* If the timeline is wider than the screen show the slider: */
    22. if(timelineWidth > screenWidth)
    23. {
    24. $('#scroll,#slider').show();
    25. $('#centered,#slider').width(120*tot);
    26.
    27. /* Making the scrollbar draggable: */
    28. $('#bar').width((120/320)*screenWidth).draggable({
    29.
    30. containment: 'parent',
    31. drag: function(e, ui) {
    32.
    33. if(!this.elem)
    34. {
    35. /* This section is executed only the first time the function is run for performance */
    36.
    37. this.elem = $('#timelineScroll');
    38.
    39. /* The difference between the slider's width and its container: */
    40. this.maxSlide = ui.helper.parent().width()-ui.helper.width();
    41.
    42. /* The difference between the timeline's width and its container */
    43. this.cWidth = this.elem.width()-this.elem.parent().width();
    44.
    45. this.highlight = $('#highlight');
    46. }
    47.
    48. /* Translating each movement of the slider to the timeline: */
    49. this.elem.css({marginLeft:'-'+((ui.position.left/this.maxSlide)*this.cWidth)+'px'});
    50.
    51. /* Moving the highlight: */
    52. this.highlight.css('left',ui.position.left)
    53. }
    54.
    55. });
    56.
    57. $('#highlight').width((120/320)*screenWidth-3);
    58.}
    59.});

    As you may have noticed in the PHP section of the tut (if not check it out – around line 33) that with each event we include a set of div elements which contain additional information (title, text and date). Those are hidden with display:none in our CSS file, and are accessed by jQuery so that the pop-up window can be populated with data without the need of sending AJAX requests (not to mention that this content is visible to search engines and is great for SEO). So it is a win-win solution.

    The data itself is being fetched in the second part of the script below:

    script.js – Part 2



    01.function showWindow(data)
    02.{
    03. /* Each event contains a set of hidden divs that hold
    04.additional information about the event: */

    05.
    06. var title = $('.title',data).text();
    07. var date = $('.date',data).text();
    08. var body = $('.body',data).html();
    09.
    10. $('<div id="overlay">').css({
    11.
    12. width:$(document).width(),
    13. height:$(document).height(),
    14. opacity:0.6
    15.
    16. }).appendTo('body').click(function(){
    17.
    18. $(this).remove();
    19. $('#windowBox').remove();
    20. });
    21.
    22. $('body').append('<div id="windowBox"><div id="titleDiv">'+title+'</div>'+body+'<div id="date">'+date+'</div></div>');
    23.
    24. $('#windowBox').css({
    25.
    26. width:500,
    27. height:350,
    28. left: ($(window).width() - 500)/2,
    29. top: ($(window).height() - 350)/2
    30. });
    31.}

    In this function we are basically treating the parameter passed from Part 1 above, where the function is called, as regular HTML and use the standard jQuery selectors thus populating the title, date and body variables.

    The Timeline Explained

    The Timeline Explained

    Step 5 – MySQL

    This last step is only needed if you plan to run the demo on your own server, or like an addition to your current site.

    To make it all tick, you have to recreate the timeline MySQL table from timeline.sql, provided in the download archive. You will also need to fill in your database credentials in connect.php.

    With this our Event Timeline is complete!


    No comments:

    Post a Comment