Jump to content

Display a list calendar using a date field


antknight

Recommended Posts

Thanks guys, you are too kind. :)

That calendar was done with Textpattern, but I built a proof-of-concept of essentially the same thing using Processwire.

Ryan gave me some huge clues on using JSON. I'll post it when I'm back at the office next week.

  • Like 4
Link to comment
Share on other sites

Renobird built this lovely calendar here. Is there a way to do this just using a date field? Is it possible to extract just the month from a date for example and foreach it?

You can extract the month of a date with 

$month = date("m",$page->date); // 03
$month = date("n",$page->date); // 3

But not sure what you're looking for. Foreach it?

Link to comment
Share on other sites

OK, it's been a while since I looked at this, and much of it was inspired or guided by Ryan.

I had to boil it down a little to make it generic enough to make sense, so this exact code hasn't been tested, but it should get you started.

Here's a proof of concept that works.

Template for your calendar page

<?php 

function pagesToJSON(PageArray $events) {
    $json = array();
    foreach($events as $event) {
        $json[] = pageToArray($event); 
    }
    return json_encode($json); 
}

function pageToArray(Page $event) {
    $data = array(
        'id' => $event->id,
        'title' => $event->title,
        'start' => date("Y-m-d H:i:s",$event->start_date),
        'end' => date("Y-m-d H:i:s",$event->end_date),
        'url' => "./$event->id", // event ID is the url segment
    );
  return $data;
}

if($input->urlSegment1) {
    // event ID provided as a URL segment to this page
    $event = $pages->get("id=$input->urlSegment1");
    include("./includes/head.inc"); 
    echo $event->title;
    echo $event->body;
    include("./includes/footer.inc"); 

} else if($config->ajax && $input->get->start && $input->get->end) {
    // fullCalendar making an ajax request of events
    $start = (int) $input->get->start;
    $end = (int) $input->get->end; 
    $events = $pages->get("/calendar/")->children("sort=start_date");
    $events = pagesToJSON($events);
    echo $events; 

} else {
    //display the calendar
    $config->scripts->add('/site/templates/assets/js/fullcalendar.min.js');
    $config->styles->add('/site/templates/assets/css/fullcalendar.css');
    $config->styles->add('/site/templates/assets/css/calendar.css');
    $config->scripts->add('/site/templates/assets/js/cal.js');

    include("./includes/head.inc");?>
    
    <div id="calendar"></div>

<?  include("./includes/footer.inc");
} // end else 
?>
 

head.inc

<!DOCTYPE HTML>
<html>
<head>
<title><?=$page->title?></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<!-- CSS includes defined via $config->styles->add -->
<?php foreach($config->styles as $url) echo "<link rel='stylesheet' type='text/css' href='$url' />";?> 
     
<!-- include jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js" type="text/javascript"></script>
<script>!window.jQuery && document.write(unescape('%3Cscript src="/site/templates/assets/js/jquery-1.6.3.min.js"%3E%3C/script%3E'))</script>

<!--js includes defined via $config->scripts->add -->  
<?php foreach($config->scripts as $url) echo "<script type='text/javascript' src='$url'></script>";?>

</head>
<body>
 

footer.inc

</body>
</html>
 
  • Like 19
Link to comment
Share on other sites

Renobird, this is amazing, can't wait to get home and try it out. Before I get my knickers in a twist though could you clarify the suggested page tree structure?

Something like:

Home

--Calendar (calendar.php template)  URL segments enabled?

  --Event 1 (event.php template with title, start date, end date etc)

  --Event 2

Is that correct?

Link to comment
Share on other sites

  • 3 weeks later...
thanks renobird that was exactly what i was looking for.

i allso add 

'allDay' => false, 

after 'url' => "./$event->id", // event ID is the url segment

and now shows  the event start - end time inside calendar
  • Like 1
Link to comment
Share on other sites

@antknight, Perhaps you could explain what you did to make it work? Might be nice for someone finding an answer when he/she searches the forum and runs into the same issues as you did.

Link to comment
Share on other sites

add this in header

      $(document).ready(function() {

    $('#calendar').fullCalendar({
      header: {
        left: 'prev,next today',
        center: 'title',
        right: 'month,agendaWeek,agendaDay'
      },
    
      editable: false,
      
      events: "json-code.php",
      
      eventRender: function(event, element, view ) { 
        if (view.name === "agendaDay") {
            element.find('.fc-event-title').append("<br/>" + event.description); 
            }
        },
      eventDrop: function(event, delta) {
        alert(event.title + ' was moved ' + delta + ' days\n' +
          '(should probably update your database)');

      },
      
      loading: function(bool) {
        if (bool) $('#loading').show();
        else $('#loading').hide();
      }

      
    });

$oldTable.remove();

this in json-code.php 


function pagesToJSON(PageArray $events) {
    $json = array();
    foreach($events as $event) {
        $json[] = pageToArray($event); 
    }
    return json_encode($json); 
}

function pageToArray(Page $event) {
    $data = array(
        'id' => $event->id,
        'title' => $event->title,
        'start' => date("Y-m-d H:i:s",$event->date_start),
        'end' => date("Y-m-d H:i:s",$event->date_end),
        'url' => "$event->url", // event ID is the url segment
        'description' => "$event->summary",
        'allDay' => false,
    );
  return $data;
}

 // end else 

$calendarPosts=$wire->pages->get('/events/')->children();
echo pagesToJSON($calendarPosts);

end in page where you want the calendar, 



 <div class="tab-pane" id="calendary">
              <div id='loading' style='display:none'>loading...</div>
              <div id='calendar' class='calendar-page'></div>
           </div>
  • Like 6
Link to comment
Share on other sites

  • 1 month later...

hi Sakkoulas.. if you can find some time can you please post the way you did it from start, what scripts to load for calendar and the full code you use to work,

thank you in advance my friend.. i need a event calendar with (event date, time, image ,map, video) for my site i try to build but i am so lost with this

Link to comment
Share on other sites

Hi pitbull 

Download the fullcalendar from the link below 
Upload the fullcalendar.css , fullcalendar.print.css and fullcalendar.js  to your server end embedded in your page header like this 
 
<link rel="stylesheet" type="text/css" href="<?php echo $config->urls->templates ?>assets/css/styleaahaeota.css">
<link href='<?php echo $config->urls->templates ?>assets/calendar/fullcalendar.css' rel='stylesheet' />
<link href='<?php echo $config->urls->templates ?>assets/calendar/fullcalendar.print.css' rel='stylesheet' media='print' />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="<?php echo $config->urls->templates ?>assets/js/bootstrap.js"></script>
<script src='<?php echo $config->urls->templates ?>assets/calendar/fullcalendar.js'></script>

add the code below in your header after the <script src='<?php echo $config->urls->templates ?>assets/calendar/fullcalendar.js'></script>

<script>
 $(document).ready(function() {
    $('#calendar').fullCalendar({
      header: {
        left: 'prev,next today',
        center: 'title',
        right: 'month,agendaWeek,agendaDay'
      },
      editable: false,
      events: "http://weborange.gr/aahaeota/json-events.php",
      
      eventRender: function(event, element, view ) { 
        var image = '<img src="'+event.img+'" />';
        if (view.name === "agendaDay") {
            element.find('.fc-event-title').append("<br/>" + event.description); 
            }
 // on event hover pop up a small discription of the event and an image, 
 // i use bootsrap framework so popoever is curently works only for
 //  bootsrap details in http://twitter.github.io/bootstrap/javascript.html#popovers
//if you dont want this,  delete it or take the code from my last post 
        element.popover({  
          html: true,
          trigger: 'hover',
            title: event.title,
            placement: 'top',
            content: image + '<span class="calendar-detail-time"> ' + event.ddate + ' until ' + event.dend + '</span>' + '<br/>' + event.description ,
        });
        },
      eventDrop: function(event, delta) {
        alert(event.title + ' was moved ' + delta + ' days\n' +
          '(should probably update your database)');

      },
      
      loading: function(bool) {
        if (bool) $('#loading').show();
        else $('#loading').hide();
      }

      
    });

$oldTable.remove();
  });
</script>
create a new php file called json-events.php and upload it in your root folder.
Inside json-events.php add the below code
<?php
include("index.php"); // bootstrap ProcessWire

function pagesToJSON(PageArray $events) {
    $json = array();
    foreach($events as $event) {
        $json[] = pageToArray($event); 
    }
    return json_encode($json); 
}

function pageToArray(Page $event) {
    $data = array(
        'id' => $event->id,
        'title' => $event->title,
        'start' => date("Y-m-d H:i",$event->date_start),
        'end' => date("Y-m-d H:i",$event->date_end),
        'url' => "$event->url", // event ID is the url segment
        'description' => "$event->summary", //event summary  for bootsrap popover
        'allDay' => false, 
        'img' => $event->images->first()->url,  //event image for bootsrap popover
        'ddate' => date("d-m-Y H:i",$event->date_start), //event date start for bootsrap popover
        'dend' => date("d-m-Y H:i",$event->date_end), //event date for bootsrap popover
    );
  return $data;
}

 // end else 

$eventPage = $wire->pages->get('/events/')->children(); 
echo pagesToJSON($eventPage);
?>

and final in the template that you want to render the calendar add 

 
<div class="tab-pane" id="calendary">
   <div id='loading' style='display:none'>loading...</div>
   <div id='calendar' class='calendar-page'></div>
</div>

that's it, you can see example  here  just go one month before from the upper left arrows

sorry for my bad english , i hope that this is going to help you

  • Like 8
Link to comment
Share on other sites

i am sory i wasnt clear,

i mean what templates i need to make to get the events show in calendar, and how to set up the event pages (what fields),

i folow the steps you tell me, and right know i only see the working calendar but no events

Sakkoulas you are very big help thank you i wiss i could help you some day..
 

Link to comment
Share on other sites

it doesnt do enything, I'm glad I could help, 

if it helps i can give you the password for my test page to see by your self the structure but is all in greek in there 

so... 

- events <-this is the parent event template, has page url 'events' it doesn't matter what fields you have in there . in this page i have put the code

<div class="tab-pane" id="calendary">

<div id='loading' style='display:none'>loading...</div>

<div id='calendar' class='calendar-page'></div>

</div>

all the children pages,of 'events' page are actually the pages that been shown in calendar

it doesn't matter what template you use but it must have the fields  

title

body

date_start

date_end

summary

headline

images
  • Like 1
Link to comment
Share on other sites

ok!! calendar start to live thank's to you Sakkoulas.. needs some experimental to make it look so nice like yours (time and title dont fit in calendar, image so big) i ques something with css.

i like a lot the  (Τελευταία Νέα) you build in your site .. was ease to do?

my friend Sakkoulas people like you make this forum so wonderful and helpful, thank you for all your help!

  • Like 1
Link to comment
Share on other sites

This is such a great thread! Thanks to all!

I'm a little confused with the dates. I have the two fields date_start and date_end in my template, defined as "Datetime". As far as I can see, this is correct?

Regardless of what date I'm entering, they are always (!) returned as "start":"1969-12-31 19:00:13","end":"1969-12-31 19:00:14".

Am I missing something here?

Regards,

Thomas

Link to comment
Share on other sites

Thanks for the hint, onjegolders!

It seems, that it's only working correct when "none" is selected in the "date output format" on the details page.

No problem, glad you got it working :) It probably means your code needs to receive the date value as a unix timestamp so it can make it's own output format.

Link to comment
Share on other sites

Thanks for the hint, onjegolders!

It seems, that it's only working correct when "none" is selected in the "date output format" on the details page.

I'm not getting it completely. Do you mean if you enable some output formatting on the date field it outputs wrong date?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...