The calendar still loads, however it just spits out an error as soon as you attempt to click or drag on something:
Uncaught TypeError: Cannot set property 'isAnimating' of undefined
I've initialized the calendar using the following code, the calendar loads, with some issues:
'use strict';
import React from 'react/addons';
React.initializeTouchEvents(true);
require("font-awesome-webpack");
//Calendar css
require('styles/normalize.css');
require('styles/main.css');
require('../../../../bower_components/fullcalendar/dist/fullcalendar.css');
require('../../../../bower_components/fullcalendar/dist/fullcalendar.print.css');
var $ = require('../../../../bower_components/jquery/dist/jquery');
//Calendar js
require('../../../../bower_components/fullcalendar/dist/fullcalendar');
const DashboardHandler = React.createClass({
componentDidMount: function(){
console.log('clicked');
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultDate: '2015-02-12',
selectable: true,
selectHelper: true,
select: function(start, end) {
var title = prompt('Event Title:');
var eventData;
if (title) {
eventData = {
title: title,
start: start,
end: end
};
$('#calendar').fullCalendar('renderEvent', eventData, true); // stick? = true
}
$('#calendar').fullCalendar('unselect');
},
editable: true,
eventLimit: true, // allow "more" link when too many events
events: [
{
title: 'All Day Event',
start: '2015-02-01'
},
{
title: 'Long Event',
start: '2015-02-07',
end: '2015-02-10'
},
{
id: 999,
title: 'Repeating Event',
start: '2015-02-09T16:00:00'
},
{
id: 999,
title: 'Repeating Event',
start: '2015-02-16T16:00:00'
},
{
title: 'Conference',
start: '2015-02-11',
end: '2015-02-13'
},
{
title: 'Meeting',
start: '2015-02-12T10:30:00',
end: '2015-02-12T12:30:00'
},
{
title: 'Lunch',
start: '2015-02-12T12:00:00'
},
{
title: 'Meeting',
start: '2015-02-12T14:30:00'
},
{
title: 'Happy Hour',
start: '2015-02-12T17:30:00'
},
{
title: 'Dinner',
start: '2015-02-12T20:00:00'
},
{
title: 'Birthday Party',
start: '2015-02-13T07:00:00'
},
{
title: 'Click for Google',
url: 'http://google.com/',
start: '2015-02-28'
}
]
});
},
render: function() {
console.log("RENDER")
return (
<div className='client-dashboard'>
<div id='calendar'></div>
</div>
);
}
});
export default DashboardHandler;
I have a webpack config file that looks like:
/*
* Webpack development server configuration
*
* This file is set up for serving the webpack-dev-server, which will watch for changes and recompile as required if
* the subfolder /webpack-dev-server/ is visited. Visiting the root will not automatically reload.
*/
'use strict';
var webpack = require('webpack');
var path = require('path');
module.exports = {
output: {
filename: 'main.js',
publicPath: '/assets/'
},
cache: true,
debug: true,
// Sourcemaps are enabled. If this is too slow, set it to false.
devtool: "eval-source-map",
noInfo: true, // --no-info option
entry: [
'webpack/hot/only-dev-server',
'./src/scripts/components/main.js'
],
stats: {
colors: true,
reasons: true
},
resolve: {
extensions: ['', '.js', '.jsx'],
alias: {
'styles': path.join(__dirname, 'src/styles'),
'components': path.join(__dirname, 'src/scripts/components/'),
'actions': path.join(__dirname, 'src/scripts/actions/'),
'stores': path.join(__dirname, 'src/scripts/stores/'),
'jquery': path.join(__dirname, 'bower_components/jquery/dist/jquery'),
'jQueryUi': path.join(__dirname, 'bower_components/fullcalendar/lib/jquery-ui.custom.min'),
'moment': path.join(__dirname, 'bower_components/moment/src/moment')
}
},
module: {
preLoaders: [{
test: /\.js(x)?$/,
exclude: /node_modules/,
loader: 'jsxhint?babel'
}],
loaders: [{
test: /\.js(x)?$/,
exclude: /node_modules/,
loader: 'react-hot!babel'
}, {
test: /\.less/,
loader: 'style-loader!css-loader!less-loader'
}, {
test: /\.css$/,
loader: 'style-loader!css-loader'
}, {
test: /\.(png|jpg)$/,
loader: 'url-loader?limit=8192'
},
{ test: /\.(woff|woff2)$/, loader: "url-loader?prefix=font/&limit=5000&mimetype=application/font-woff" },
{ test: /\.ttf$/, loader: "file-loader" },
{ test: /\.eot$/, loader: "file-loader" },
{ test: /\.svg$/, loader: "file-loader" },
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&minetype=application/font-woff" },
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
]
};
Jquery and all of the calendars dependancies appear to be defined. The issue is being thrown in the following function in the calendar source code:
// Causes the element to stop following the mouse. If shouldRevert is true, will animate back to original position.
// callback gets invoked when the animation is complete. If no animation, it is invoked immediately.
stop: function(shouldRevert, callback) {
var _this = this;
var revertDuration = this.options.revertDuration;
function complete() {
this.isAnimating = false;
_this.destroyEl();
this.top0 = this.left0 = null; // reset state for future updatePosition calls
if (callback) {
callback();
}
}
if (this.isFollowing && !this.isAnimating) { // disallow more than one stop animation at a time
this.isFollowing = false;
$(document).off('mousemove', this.mousemoveProxy);
if (shouldRevert && revertDuration && !this.isHidden) { // do a revert animation?
this.isAnimating = true;
this.el.animate({
top: this.top0,
left: this.left0
}, {
duration: revertDuration,
complete: complete
});
}
else {
complete();
}
}
},
It looks like a really weird scoping issue caused by webpack, I'm at a loss as to how to fix it. Based on the stack trace, it also looks like the touch start event doesn't even fire:
Uncaught TypeError: Cannot set property 'isAnimating' of undefinedcomplete @ fullcalendar.js?2811:2551stop @ fullcalendar.js?2811:2577dragStop @ fullcalendar.js?2811:3761trigger @ fullcalendar.js?2811:2137dragStop @ fullcalendar.js?2811:2090dragStop @ fullcalendar.js?2811:2409stopDrag @ fullcalendar.js?2811:2080stopListening @ fullcalendar.js?2811:2103mouseup @ fullcalendar.js?2811:2071(anonymous function) @ fullcalendar.js?2811:760dispatch @ jquery.js?0403:4435jQuery.event.add.elemData.handle @ jquery.js?0403:4121
If it's a scoping issue it might not be webpack related but react doing some autobinding magic in such a way that it's not compatible with how the jquery plugin works.
If that's truly the case, you could tweak the fullcalendar code for the calls to
callback()andcomplete()tocallback.call(this)andcomplete.call(this)so that the expected context is set every time.Modifying the plugin source is not a particularly appealing solution, but it should get you by in a pinch.