diff --git a/README.md b/README.md index 7463b7ee..0ed7d3cf 100644 --- a/README.md +++ b/README.md @@ -189,7 +189,7 @@ timekitCreateEvent: { **FullCalendar** -You can supply and overwrite all the FullCalendar settings directly here. +You can supply and override all the [FullCalendar settings](http://fullcalendar.io/docs/): ```javascript fullCalendar: { @@ -199,23 +199,46 @@ fullCalendar: { right: 'today, prev, next' }, views: { - basic: { - columnFormat: 'dddd M/D', - }, agenda: { - columnFormat: 'ddd\n M/D', - slotLabelFormat: 'ha', - displayEventEnd: false + displayEventEnd: false } }, - timeFormat: 'h:mma', allDaySlot: false, scrollTime: '08:00:00', timezone: 'local', defaultView: sizing.view, // Inserted based on the current width of the widget height: sizing.height, // Inserted based on the current width of the widget - eventClick: fn(), // Handled internally in Booking.js (overwrite if you want to replace the booking page) - windowResize: fn() // Recalculates the view and height based on the widget's width (if resized) + eventClick: function(event), // Handled internally in Booking.js (overwrite if you want to replace the booking page) + windowResize: function(view) // Recalculates the view and height based on the widget's width (if resized) +} +``` + +*See below for FullCalendar language support.* + +**Localization** + +For quick localization of time/date formats, we provide a simple "preset" setting, `timeDateFormat`, that sets a range of different FullCalendar and localization settings. + +By default, it's set to "12-hour clock, M/D/Y date format, Sunday first day of week" (`12h-mdy-sun`). It can be changed to "24-hour clock, D/M/Y date format, Monday first day of week" (`24h-dmy-mon`). + +```javascript +localization: { + timeDateFormat: '12h-mdy-sun', // Default, alternative mode "24h-dmy-mon", + bookingDateFormat: 'MMMM D, YYYY', // Override the default date format on the booking page + bookingTimeFormat: 'h:mma' // Override the default time format on the booking page +}, +``` + +For full language support, FullCalendar also takes a ["lang" option](http://fullcalendar.io/docs/text/lang/), accompanied by a language file. + +Remember to set `localization.timeDateFormat` to false so it doesn't override the language file's settings. See `/examples/language.htm` for full implementation example. + +```javascript +fullCalendar: { + lang: 'de' +}, +localization: { + timeDateFormat: false } ``` diff --git a/examples/language.htm b/examples/language.htm new file mode 100644 index 00000000..10eddb86 --- /dev/null +++ b/examples/language.htm @@ -0,0 +1,37 @@ + + + + + Booking.js FullCalendar language support + + + + + + + +
+ +
+ + + diff --git a/examples/single.htm b/examples/single.htm index 71f2c2c6..3df8e0d6 100644 --- a/examples/single.htm +++ b/examples/single.htm @@ -19,7 +19,6 @@ apiToken: 'XT1JO879JF1qUXXzmETD5ucgxaDwsFsd', calendar: '22f86f0c-ee80-470c-95e8-dadd9d05edd2', avatar: '../misc/avatar-doc.jpg', - autoload: true, timekitConfig: { app: 'bookingjs-demo' } diff --git a/src/defaults.js b/src/defaults.js index fb061208..99433f88 100644 --- a/src/defaults.js +++ b/src/defaults.js @@ -4,7 +4,7 @@ * Default configuration for for Booking.js */ -module.exports = { +var primary = { // email: '', // apiToken: '', @@ -34,16 +34,10 @@ module.exports = { right: 'today, prev, next' }, views: { - basic: { - columnFormat: 'dddd M/D', - }, agenda: { - columnFormat: 'ddd\n M/D', - slotLabelFormat: 'ha', displayEventEnd: false } }, - timeFormat: 'h:mma', allDaySlot: false, scrollTime: '08:00:00', timezone: 'local', @@ -52,10 +46,63 @@ module.exports = { }, localization: { showTimezoneHelper: true, - timeDateFormat: '12h-mdy-sun', - bookingDateFormat: 'MMMM D, YYYY', - bookingTimeFormat: 'h:mma' + timeDateFormat: '12h-mdy-sun' }, callbacks: {} }; + +// Preset: timeDateFormat = '24h-dmy-mon' +var timeDateFormat24hdmymon = { + + fullCalendar: { + timeFormat: 'HH:mm', + firstDay: 1, + views: { + basic: { + columnFormat: 'dddd D/M' + }, + agenda: { + columnFormat: 'ddd\n D/M', + slotLabelFormat: 'HH:mm' + } + } + }, + localization: { + bookingDateFormat: 'D. MMMM YYYY', + bookingTimeFormat: 'HH:mm' + } + +}; + +// Preset: timeDateFormat = '12h-mdy-sun' +var timeDateFormat12hmdysun = { + + fullCalendar: { + timeFormat: 'h:mma', + firstDay: 0, + views: { + basic: { + columnFormat: 'dddd M/D', + }, + agenda: { + columnFormat: 'ddd\n M/D', + slotLabelFormat: 'ha' + } + }, + }, + localization: { + bookingDateFormat: 'MMMM D, YYYY', + bookingTimeFormat: 'h:mma' + } + +}; + +// Export objects +module.exports = { + primary: primary, + presets: { + timeDateFormat24hdmymon: timeDateFormat24hdmymon, + timeDateFormat12hmdysun: timeDateFormat12hmdysun + } +}; diff --git a/src/main.js b/src/main.js index 3ead3da5..e8b72f38 100644 --- a/src/main.js +++ b/src/main.js @@ -11,13 +11,13 @@ */ // External depenencies -require('fullcalendar'); -var $ = require('jquery'); -var timekit = require('timekit-sdk'); -var moment = require('moment'); +var $ = require('jquery'); +window.fullcalendar = require('fullcalendar'); +var moment = window.moment = require('moment'); +var timekit = require('timekit-sdk'); // Internal dependencies -var utils = require('./utils'); +var utils = require('./utils'); var defaultConfig = require('./defaults'); // Main library @@ -41,29 +41,31 @@ function TimekitBooking() { // Make sure DOM element is ready and clean it var prepareDOM = function() { + rootTarget = $(config.targetEl); if (rootTarget.length === 0) { throw new Error('TimekitBooking - No target DOM element was found (' + config.targetEl + ')'); } rootTarget.addClass('bookingjs'); rootTarget.children(':not(script)').remove(); + }; // Setup the Timekit SDK with correct credentials var timekitSetup = function() { - var args = {}; + var args = {}; $.extend(true, args, config.timekitConfig); timekit.configure(args); timekit.setUser(config.email, config.apiToken); + }; // Fetch availabile time through Timekit SDK var timekitFindTime = function() { var args = { emails: [config.email] }; - $.extend(args, config.timekitFindTime); utils.doCallback('findTimeStarted', config, args); @@ -80,6 +82,7 @@ function TimekitBooking() { utils.doCallback('findTimeFailed', config, response); throw new Error('TimekitBooking - An error with Timekit FindTime occured, context: ' + response); }); + }; // Calculate and display timezone helper @@ -124,6 +127,7 @@ function TimekitBooking() { utils.doCallback('getUserTimezoneFailed', config, response); throw new Error('TimekitBooking - An error with Timekit getUserTimezone occured, context: ' + response); }); + }; // Setup and render FullCalendar @@ -217,9 +221,13 @@ function TimekitBooking() { utils.doCallback('showBookingPage', config); var template = require('./templates/booking-page.html'); + + var dateFormat = config.localization.bookingDateFormat || moment.localeData().longDateFormat('LL'); + var timeFormat = config.localization.bookingTimeFormat || moment.localeData().longDateFormat('LT'); + bookingPageTarget = $(template({ - chosenDate: moment(eventData.start).format(config.localization.bookingDateFormat), - chosenTime: moment(eventData.start).format(config.localization.bookingTimeFormat) + ' to ' + moment(eventData.end).format(config.localization.bookingTimeFormat), + chosenDate: moment(eventData.start).format(dateFormat), + chosenTime: moment(eventData.start).format(timeFormat) + ' - ' + moment(eventData.end).format(timeFormat), start: moment(eventData.start).format(), end: moment(eventData.end).format(), closeIcon: require('!svg-inline!./assets/close-icon.svg'), @@ -266,6 +274,7 @@ function TimekitBooking() { utils.doCallback('closeBookingPage', config); bookingPageTarget.removeClass('show'); + setTimeout(function(){ bookingPageTarget.remove(); }, 200); @@ -279,10 +288,10 @@ function TimekitBooking() { e.preventDefault(); - var formElement = $(form); - utils.doCallback('submitBookingForm', config); + var formElement = $(form); + // Abort if form is submitting, have submitted or does not validate if(formElement.hasClass('loading') || formElement.hasClass('success') || !e.target.checkValidity()) { var submitButton = formElement.find('.bookingjs-form-button'); @@ -312,6 +321,7 @@ function TimekitBooking() { utils.doCallback('createEventFailed', config, response); throw new Error('TimekitBooking - An error with Timekit createEvent occured, context: ' + response); }); + }; // Create new event through Timekit SDK @@ -331,6 +341,7 @@ function TimekitBooking() { utils.doCallback('createEventStarted', config, args); return timekit.createEvent(args); + }; // Render the powered by Timekit message @@ -362,31 +373,15 @@ function TimekitBooking() { var newConfig = {}; var localizationConfig = {}; - // Handle FullCalendar shorthand localization + // Handle presets if(suppliedConfig.localization && suppliedConfig.localization.timeDateFormat === '24h-dmy-mon') { - localizationConfig = { - fullCalendar: { - timeFormat: 'HH:mm', - firstDay: 1, - views: { - agenda: { - columnFormat: 'ddd\n D/M', - slotLabelFormat: 'HH:mm' - }, - basic: { - columnFormat: 'dddd D/M' - } - } - }, - localization: { - bookingDateFormat: 'D. MMMM YYYY', - bookingTimeFormat: 'HH:mm' - } - }; + localizationConfig = defaultConfig.presets.timeDateFormat24hdmymon; + } else if (suppliedConfig.localization && suppliedConfig.localization.timeDateFormat === '12h-mdy-sun') { + localizationConfig = defaultConfig.presets.timeDateFormat12hmdysun; } // Extend the default config with supplied settings - $.extend(true, newConfig, defaultConfig, localizationConfig, suppliedConfig); + $.extend(true, newConfig, defaultConfig.primary, localizationConfig, suppliedConfig); // Check for required settings if(!newConfig.email || !newConfig.apiToken || !newConfig.calendar) { @@ -402,7 +397,9 @@ function TimekitBooking() { // Get library config var getConfig = function() { + return config; + }; // Render method @@ -457,15 +454,19 @@ function TimekitBooking() { }; var destroy = function() { + prepareDOM(); config = {}; return this; + }; // The fullCalendar object for advanced puppeting var fullCalendar = function() { + if (calendarTarget.fullCalendar === undefined) { return undefined; } return calendarTarget.fullCalendar.apply(calendarTarget, arguments); + }; // Expose methods