I am trying to display the excellent fullcalendar in an extjs window that has loaded in response to a button click.
I can get the calendar to display in the window as follows:
// .. grid config..
//component bar
tbar: 开发者_如何学Go[{
text:'Calendar',
tooltip: 'View leave calendar',
disabled: false,
iconCls:'icon-thisYr',//create icon
handler: function(){
var win;
// create the leave calendar window on the first click and reuse on subsequent clicks
if(!win){
win = new Ext.Window({
layout:'fit',
width:750,
height:750,
closeAction:'hide',
plain: false,
//left: 150,
//top: 10,
items: [
// Set to div id in default.ctp to display jquery fullcalendar when button is clicked.
calendar
],
buttons: [{
text: 'Close',
handler: function(){
win.hide();
}
}]
})
win.show();
}
}
}]
//etc rest of grid
and in my default.ctp view:
<!--Set placeholder for jquery fullcalendar called from events grid tbar button-->
<!--I think - set 'items' property on Ext.window to 'calendar' div-->
<div id="hello-win" class="x-hidden">
<div class="x-window-header">Annual Leave Calendar</div>
<!--Placeholder for fullcalendar-->
<div id="calendar">
<script type='text/javascript'>
$(document).ready(function() {
$('#calendar').fullCalendar({});
</script>
</div>
</div>
I am sure this is not the correct way to do this as the calendar only shows up sometimes and if I add some options to the fullcalendar initialisation then it won't display at all.
Any help on this would be much appreciated.
For the benefit of others here is how I implemented fullcalendar, extjs and cakephp. Thanks to Upper Stage for earlier help.
- Include all the fullcalendar files in your default.ctp before any extjs includes.
- Don't include the fullcalendar print css file as it seems to interfere with custom colouring.
Create a feed function in your controller (events controller here) similar to below:
function feed() {
// jquery fullcalendar feed via feed.ctp Configure::write('debug', '0'); //turn debugging off; debugging breaks ajax $this->layout = "ajax"; //set the layout to Ajax so the ajax doesn't break $this->Event->recursive = 1; //1. Transform request parameters to MySQL datetime format. $mysqlstart = date( 'Y-m-d H:i:s', $this->params['url']['start']); $mysqlend = date('Y-m-d H:i:s', $this->params['url']['end']); //2. Get the events corresponding to the time range $conditions = array('Event.event_date BETWEEN ? AND ?' => array($mysqlstart,$mysqlend)); $events = $this->Event->find('all',array('conditions' =>$conditions)); //print_r($events); //3. Create the json array $rows = array(); //var $backgroundColor for ($a=0; count($events)> $a; $a++) { //Is it an all day event - set to false? $all = ($events[$a]['Event']['allday'] == 0); // color each leave type if($events[$a]['Event']['leave_type'] == 'Annual Leave') {$backgroundColor = "green";} elseif($events[$a]['Event']['leave_type'] == 'Sick') {$backgroundColor = "red";} elseif ($events[$a]['Event']['leave_type'] == 'UA') {$backgroundColor = "orange";} // set nemonic for split shift if($events[$a]['Event']['split_shift'] == 1) {$splitShift = "+";} else {$splitShift = "";} //Create an event entry $rows[] = array('id' => $events[$a]['Event']['id'], 'title' => $splitShift.$events[$a]['Employee']['name'], 'start' => date('Y-m-d H:i', strtotime($events[$a]['Event']['event_date'])), 'backgroundColor' => $backgroundColor ); } $this->set('events',json_encode($rows)); //send events to the view }
This retrieves all the events between the start and end date params that fullcalendar sends with the url. It also maps and formats your database fields to fit the standard fullcalendar requirement.
Next add a view file called feed.ctp and put the events variable in it (within php tags of course):
echo $events;
In your ext code (say to pop up a window with fullcalendar in it do the following:
win = new Ext.Window({ layout:'fit', width:650, height:650, closeAction:'close', plain: false, title:'Annual Leave Calendar - Somerville House', iconCls:'icon-thisYr',//create icon modal: true, items: [ { xtype: 'box', autoEl: { tag: 'div', html: '<div id="calendar"></div>' } }], listeners: { // when the window is activated 'activate': function() { // call jquery fullcalendar $('#calendar').fullCalendar({ header: { left: 'prevYear,prev,today,next,nextYear', center: 'title', right: 'month,agendaWeek,agendaDay' }, //height: 650, aspectRatio: 2, eventTextColor: '#e5e5e5', // get calendar feed from events/feed controller function and return via feed.ctp events: 'http://'+host+'/shiftplanner/events/feed' }); } } })
Using autoEl we can place the div that fullcalendar needs to be rendered in. We then listen to the activate event of the window and simply initialise fullcalendar in the normal way. No problem!
I would take a different approach. Instead of the following...
items: [
// Set to div id in default.ctp ...
calendar
],
.... I would create an empty DIV in the Ext JS window (using autoEl, for example) and then render the jQuery fullcalendar into the window's DIV. I prefer this approach for several reasons: sometimes developers destroy windows after each use, it makes more sense to me to create window assets (div for the calendar) near the creation of the window, I create the calendar only if the user cares to view it, ...
I hope this helps.
精彩评论