999 lines
29 KiB
XML
999 lines
29 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<javascript app="calendar">
|
|
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.main.js" javascript_type="controller" javascript_version="102002" javascript_position="1000050"><![CDATA[/**
|
|
* Invision Community
|
|
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
|
*
|
|
* ips.browse.main.js - Calendar main browsing controller
|
|
*
|
|
* Author: Rikki Tissier
|
|
*/
|
|
;( function($, _, undefined){
|
|
"use strict";
|
|
|
|
ips.controller.register('calendar.front.browse.main', {
|
|
|
|
_ajaxObj: null,
|
|
|
|
initialize: function () {
|
|
this.on( 'click', '[data-action="changeView"]', this.changeView );
|
|
this.on( window, 'statechange', this.stateChange );
|
|
this.setup();
|
|
},
|
|
|
|
/**
|
|
* Controller setup method
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
setup: function () {
|
|
History.pushState( { controller: 'calendarView' }, document.title, window.location.href );
|
|
},
|
|
|
|
/**
|
|
* Changes the calendar view dynamically
|
|
*
|
|
* @param {event} e Event object
|
|
* @returns {void}
|
|
*/
|
|
changeView: function (e) {
|
|
e.preventDefault();
|
|
|
|
// Load the url via ajax instead
|
|
var self = this;
|
|
var title = $( e.currentTarget ).attr('title');
|
|
var url = $( e.currentTarget ).attr('href');
|
|
|
|
History.pushState( { controller: 'calendarView' }, title, url );
|
|
},
|
|
|
|
/**
|
|
* Event handler for history state changes
|
|
*
|
|
* @param {event} e Event object
|
|
* @returns {void}
|
|
*/
|
|
stateChange: function () {
|
|
var state = History.getState();
|
|
|
|
if( _.isUndefined( state.data.controller ) || state.data.controller != 'calendarView' ) {
|
|
return;
|
|
}
|
|
|
|
// Track page view
|
|
ips.utils.analytics.trackPageView( state.url );
|
|
|
|
this._updateView( state.url, state.title )
|
|
},
|
|
|
|
/**
|
|
* Loads a new view
|
|
*
|
|
* @param {string} url URL to load
|
|
* @param {string} title New browser title
|
|
* @returns {void}
|
|
*/
|
|
_updateView: function (url, title) {
|
|
var self = this;
|
|
|
|
if( this._ajaxObj && _.isFunction( this._ajaxObj.abort ) ){
|
|
this._ajaxObj.abort();
|
|
}
|
|
|
|
this._setLoading( true );
|
|
|
|
this._ajaxObj = ips.getAjax()( url, {
|
|
showLoading: true
|
|
} )
|
|
.done( function (response) {
|
|
self.scope.html( response );
|
|
|
|
$( document ).trigger( 'contentChange', [ self.scope ] );
|
|
|
|
History.pushState( { controller: 'calendarView' }, title, url );
|
|
})
|
|
.always( function () {
|
|
self._setLoading( false );
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Toggles the loading state on the view
|
|
*
|
|
* @param {boolean} state Enable the loading state?
|
|
* @returns {void}
|
|
*/
|
|
_setLoading: function (state) {
|
|
if( state ){
|
|
this.scope.animate( { opacity: 0.6 }, 'fast' );
|
|
} else {
|
|
this.scope.animate( { opacity: 1 }, 'fast' );
|
|
}
|
|
}
|
|
});
|
|
}(jQuery, _));]]></file>
|
|
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.monthView.js" javascript_type="controller" javascript_version="102002" javascript_position="1000050"><![CDATA[/**
|
|
* Invision Community
|
|
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
|
*
|
|
* ips.browse.monthView.js - Month view controller
|
|
*
|
|
* Author: Rikki Tissier
|
|
*/
|
|
;( function($, _, undefined){
|
|
"use strict";
|
|
|
|
ips.controller.register('calendar.front.browse.monthView', {
|
|
|
|
_emptyEvent: "<li class='cEvents_event cEvents_empty' data-eventid='0'><span></span></a></li>",
|
|
|
|
initialize: function () {
|
|
this.setup();
|
|
},
|
|
|
|
/**
|
|
* Setup method
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
setup: function () {
|
|
this._alignEvents();
|
|
},
|
|
|
|
|
|
_alignEvents: function () {
|
|
// Lets start by getting all active days in the current calendar
|
|
var days = this.scope.find('.cCalendar_date');
|
|
var currentPositions = [];
|
|
var self = this;
|
|
|
|
_.each( days, function (day) {
|
|
var day = $( day );
|
|
var dayNumber = day.find('.cCalendar_dayNumber').text();
|
|
var weekStart = false;
|
|
|
|
if( day.closest('td').is('tr > td:first-child') ){
|
|
weekStart = true;
|
|
}
|
|
|
|
// Get events for this day
|
|
var events = day.find('.cEvents_ranged [data-eventID]');
|
|
|
|
// If there's no events, we can skip this day
|
|
if( !events.length ){
|
|
currentPositions = [];
|
|
return;
|
|
}
|
|
|
|
// Build a wrapper into which we'll move our events
|
|
var wrapper = $("<ul/>").addClass('cEvents');
|
|
var spaces = 0;
|
|
|
|
// Now we loop over currentPositions (from the previous day), and try and arrange today's events
|
|
// in the same order
|
|
if( currentPositions.length ){
|
|
var doneEvent = false;
|
|
|
|
for( var i = 0; i < currentPositions.length; i++ ){
|
|
if( events.filter('[data-eventID="' + currentPositions[i] + '"]').length ){
|
|
wrapper.append( events.filter('[data-eventID="' + currentPositions[i] + '"]') );
|
|
doneEvent = true;
|
|
} else {
|
|
|
|
// If this is the first day of the week, we won't bother adding spacers unless we've already done an event today
|
|
// This prevents lots of unnecessary spacers carrying over from the previous row
|
|
if( !weekStart || doneEvent ){
|
|
wrapper.append( self._emptyEvent );
|
|
spaces++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var remainingEvents = day.find('.cEvents_ranged [data-eventID]');
|
|
|
|
// If we have any remaining events, and there's gaps available, we can move those events into the gaps rather than
|
|
// just putting them at the end
|
|
if( spaces && remainingEvents.length ){
|
|
var availableSpaces = wrapper.find('[data-eventID="0"]');
|
|
|
|
// If we have a space and an event, move the event into that space
|
|
for( var i = 0; i <= spaces; i++ ){
|
|
if( remainingEvents[ i ] && availableSpaces[ i ] ){
|
|
$( availableSpaces[ i ] ).replaceWith( $( remainingEvents[ i ] ) );
|
|
}
|
|
}
|
|
|
|
// Update remaining events again
|
|
remainingEvents = day.find('.cEvents_ranged [data-eventID]');
|
|
}
|
|
|
|
// Add in remaining events
|
|
wrapper.append( remainingEvents );
|
|
|
|
// Replace the existing wrapper with the new, correctly-ordered one
|
|
day.find('.cEvents_ranged > .cEvents').replaceWith( wrapper );
|
|
|
|
// Now we need to build a new currentPositions array for this day, so that the following
|
|
// day can use it to do its thing
|
|
currentPositions = [];
|
|
|
|
_.each( day.find('.cEvents_ranged [data-eventID]'), function (event) {
|
|
var eventID = parseInt( $( event ).attr('data-eventID') );
|
|
|
|
if( eventID === 0 ){
|
|
currentPositions.push('-');
|
|
} else if( _.isNumber( eventID ) && !_.isNaN( eventID ) ){
|
|
currentPositions.push( eventID );
|
|
}
|
|
});
|
|
});
|
|
|
|
// Now get all rows and cells to recalculate height
|
|
_.each( this.scope.find('tr'), function (row) {
|
|
|
|
// Don't bother if there's no birthdays in this row
|
|
if( !$( row ).find('.cCalendar_birthdays').length ){
|
|
return;
|
|
}
|
|
|
|
var cells = $( row ).find('td.cCalendar_date');
|
|
var maxHeightCell = _.max( cells, function (cell) {
|
|
return parseInt( $( cell ).height() );
|
|
});
|
|
|
|
if( !_.isElement( maxHeightCell ) ){
|
|
return;
|
|
}
|
|
|
|
// Set the div height
|
|
cells.find('> div').css({
|
|
height: $( maxHeightCell ).height() + 20 + 'px'
|
|
});
|
|
});
|
|
}
|
|
});
|
|
}(jQuery, _));]]></file>
|
|
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.dates.js" javascript_type="controller" javascript_version="102002" javascript_position="1000100"><![CDATA[/**
|
|
* Invision Community
|
|
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
|
*
|
|
* ips.submit.dates.js - Helper for date selection enhancements
|
|
*
|
|
* Author: Rikki Tissier
|
|
*/
|
|
;( function($, _, undefined){
|
|
"use strict";
|
|
|
|
ips.controller.register('calendar.front.submit.dates', {
|
|
|
|
initialize: function () {
|
|
this._hasFocusedEventEnd = false;
|
|
|
|
this.on( 'click', '[data-action="updateTimezone"]', this.updateTimezone );
|
|
|
|
// Monitor focus in recurring event input fields and select appropriate radio button
|
|
this.on( 'focus', 'input[name="repeat_end_occurrences"]', function(){ $('#event_repeat_end_afterx').prop('checked', true); } );
|
|
this.on( 'focus', 'input[name="repeat_end_date"]', function(){ $('#event_repeat_end_ondate').prop('checked', true); } );
|
|
|
|
this.on( 'change', 'input, select', this.checkForSummaryChange );
|
|
this.on( 'change', '#check_single_day, #check_all_day', this.toggleFields );
|
|
this.on( 'click', '#elRecurRemove', this.disableRecurring );
|
|
this.on( 'change', 'input[name="event_dates[start_date]"]', this.setEndDateOnStartChange );
|
|
this.on( 'change', '#event_end_date', this.setHasFocusedEventOnEndChange );
|
|
|
|
$( window ).on( 'resize', _.bind( this._resizeEndGrid, this ) );
|
|
|
|
this.on( 'click', '[data-action="updateRepeat"]', this.finishRepeat );
|
|
|
|
this._checkAndSetEventEndState();
|
|
|
|
this.setup();
|
|
},
|
|
|
|
/**
|
|
* On page load check to see what the current state of the end date is. If its set lets just go ahead and ignore any start date changes
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
_checkAndSetEventEndState: function() {
|
|
var eventEndDate = $("#event_end_date");
|
|
var date = eventEndDate.val();
|
|
|
|
if (!this._hasFocusedEventEnd && this._isValidEndDate(date)) {
|
|
this._hasFocusedEventEnd = true;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Is the date passed in a valid date?
|
|
*
|
|
* @param {date} date Date to check
|
|
* @returns {boolean}
|
|
*/
|
|
_isValidEndDate: function(date) {
|
|
|
|
var tempDate = new Date(date);
|
|
|
|
if(!isNaN(tempDate.getDate())) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
},
|
|
|
|
/**
|
|
* If the end field has changed from input go ahead and ignore any start date changes
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
setHasFocusedEventOnEndChange: function() {
|
|
this._hasFocusedEventEnd = true;
|
|
},
|
|
|
|
/**
|
|
* Event handler, handles changes to the start date
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
setEndDateOnStartChange: function() {
|
|
var isSameDay = $("#check_single_day").is(":checked");
|
|
var eventStartDate = $('input[name="event_dates[start_date]');
|
|
var eventEndDate = $("#event_end_date");
|
|
|
|
if(!isSameDay && !this._hasFocusedEventEnd) {
|
|
if( ips.utils.time.supportsHTMLDate() ) {
|
|
eventEndDate.val(eventStartDate.val());
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Finish setting the options
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
finishRepeat: function () {
|
|
this._updateSummary();
|
|
$('#elRecurEdit_menu').trigger('closeMenu');
|
|
},
|
|
|
|
/**
|
|
* Setup method
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
setup: function () {
|
|
this._updateSummary();
|
|
this.toggleFields();
|
|
this.updateTimezone();
|
|
|
|
// Make Event End cell as big as Event Start cell
|
|
this._resizeEndGrid();
|
|
},
|
|
|
|
/**
|
|
* Manual toggle functionality for the Single/All Day checkboxes
|
|
*
|
|
* @param {event} e Event object
|
|
* @returns {void}
|
|
*/
|
|
toggleFields: function (e) {
|
|
var singleDay = this.scope.find('#check_single_day');
|
|
var allDay = this.scope.find('#check_all_day');
|
|
var self = this;
|
|
|
|
var toggles = {
|
|
start_time_wrap: true,
|
|
end_time_wrap: true,
|
|
event_end_date_wrap: true,
|
|
elDateGrid_arrow: true,
|
|
elDateGrid_end: true
|
|
};
|
|
|
|
// Single day, not all day
|
|
if( singleDay.is(':checked') && !allDay.is(':checked') ){
|
|
toggles.event_end_date_wrap = false;
|
|
// Single day, all day
|
|
} else if( singleDay.is(':checked') && allDay.is(':checked') ){
|
|
toggles.elDateGrid_arrow = false;
|
|
toggles.elDateGrid_end = false;
|
|
toggles.start_time_wrap = false;
|
|
// Multiple days, all day
|
|
} else if( !singleDay.is(':checked') && allDay.is(':checked') ){
|
|
toggles.start_time_wrap = false;
|
|
toggles.end_time_wrap = false;
|
|
}
|
|
|
|
// Hide appropriate elements
|
|
_.each( toggles, function (val, key) {
|
|
self.scope.find( '#' + key ).toggle( val );
|
|
});
|
|
|
|
// Manual check for ful;-width start date
|
|
this.scope.find('#elDateGrid_start').toggleClass('ipsGrid_span5', this.scope.find('#elDateGrid_end').is(':visible') );
|
|
},
|
|
|
|
/**
|
|
* Monitor changes to the repeat options and update the summary
|
|
*
|
|
* @param {event} e Event object
|
|
* @param {object} data Event data object
|
|
* @returns {void}
|
|
*/
|
|
checkForSummaryChange: function (e) {
|
|
if( $( e.currentTarget ).attr('name').startsWith('event_dates[') ){
|
|
this._updateSummary();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Updates the timezone value both in the hidden field and in the display to the end user
|
|
*
|
|
* @param {event} e Event object
|
|
* @returns {void}
|
|
*/
|
|
updateTimezone: function (e) {
|
|
if( e ){
|
|
e.preventDefault();
|
|
}
|
|
|
|
// Update displayed timezone
|
|
this.scope.find('[data-role="timezone_display"]').text( $('#event_timezone option:selected').data('abbreviated') ).trigger('closeMenu');
|
|
},
|
|
|
|
/**
|
|
* Removes the Repeat summary and unchecks the Repeat checkbox
|
|
*
|
|
* @param {event} e Event object
|
|
* @param {object} data Event data object
|
|
* @returns {void}
|
|
*/
|
|
disableRecurring: function (e) {
|
|
e.preventDefault();
|
|
|
|
this.scope.find('#elRepeatCb').prop( 'checked', false );
|
|
this._updateSummary();
|
|
},
|
|
|
|
/**
|
|
* Finalize our recurring options
|
|
*
|
|
* @param {event} e Event object
|
|
* @param {object} data Event data object
|
|
* @returns {void}
|
|
*/
|
|
finishRepeatConfiguration: function (e, data) {
|
|
e.preventDefault();
|
|
|
|
// Copy the summary from the menu to the main display and close the menu
|
|
this.scope.find('[data-role="recur_summary_final"]').text( this.scope.find('[data-role="recur_summary"]').text() );
|
|
this.scope.find('#elRecurEdit').trigger('closeMenu');
|
|
},
|
|
|
|
/**
|
|
* Update the recurring string
|
|
*
|
|
* @param {event} e Event object
|
|
* @param {object} data Event data object
|
|
* @returns {void}
|
|
*/
|
|
_updateSummary: function () {
|
|
var summary = this.scope.find('[data-role="recurringSummary"]');
|
|
|
|
// Update repeating text
|
|
if( this.scope.find('#elRepeatCb').is(':checked') ){
|
|
summary.text( this._getSummary() );
|
|
this.scope.find('#elRepeatRow_hidden').hide();
|
|
this.scope.find('#elRepeatRow_shown').show();
|
|
} else {
|
|
summary.html( "<em class='ipsType_light'>" + ips.getString('doesnt_repeat') + "</em>" );
|
|
this.scope.find('#elRepeatRow_hidden').show();
|
|
this.scope.find('#elRepeatRow_shown').hide();
|
|
}
|
|
|
|
// Update the dates
|
|
this.scope.find('[data-role="dateSummary"]').html( this._dateSummary() );
|
|
},
|
|
|
|
/**
|
|
* Builds a summary of the selected dates/times
|
|
*
|
|
* @returns {string}
|
|
*/
|
|
_dateSummary: function () {
|
|
// Build start date
|
|
var startDate = ips.utils.time.getDateFromInput( this.scope.find('input[name="event_dates[start_date]"]') );
|
|
var singleDay = this.scope.find('#check_single_day');
|
|
var allDay = this.scope.find('#check_all_day');
|
|
|
|
// If there's no start time, then abandon showing any summary for now
|
|
if( !ips.utils.time.isValidDateObj( startDate ) || startDate.getFullYear() < 1900 ) {
|
|
return '';
|
|
}
|
|
|
|
ips.utils.time.removeTimezone( startDate );
|
|
|
|
var startDateString = ips.utils.time.localeDateString( startDate, { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric', timeZone: 'UTC' } );
|
|
var startTime = this._getTime( this.scope.find('input[name="event_dates[start_time]"]').val() );
|
|
var endTime = this._getTime( this.scope.find('input[name="event_dates[end_time]"]').val() );
|
|
var endDate = ips.utils.time.getDateFromInput( this.scope.find('input[name="event_dates[end_date]"]') );
|
|
var endDateString = '';
|
|
|
|
// If we have a valid end date...
|
|
if( !singleDay.is(':checked') && ips.utils.time.isValidDateObj( endDate ) ){
|
|
ips.utils.time.removeTimezone( endDate );
|
|
endDateString = ips.utils.time.localeDateString( endDate, { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric', timeZone: 'UTC' } );
|
|
}
|
|
|
|
// Now build strings
|
|
var finalString = '';
|
|
|
|
if( singleDay.is(':checked') && !allDay.is(':checked') ){
|
|
finalString = ips.getString( 'single_not_allday', { startDate: startDateString, startTime: startTime, endTime: endTime } );
|
|
} else if ( ( !singleDay.is(':checked') && !allDay.is(':checked') ) && endDateString && startTime && endTime ) {
|
|
finalString = ips.getString( 'not_single_not_allday', { startDate: startDateString, endDate: endDateString, startTime: startTime, endTime: endTime } );
|
|
} else if( !singleDay.is(':checked') && allDay.is(':checked') && endDateString ) {
|
|
finalString = ips.getString( 'not_single_allday', { startDate: startDateString, endDate: endDateString } );
|
|
} else {
|
|
finalString = ips.getString( 'single_allday', { startDate: startDateString } );
|
|
}
|
|
|
|
return finalString;
|
|
},
|
|
|
|
/**
|
|
* Returns the given time, or a placeholder string if empty
|
|
*
|
|
* @param {string} time Time string
|
|
* @returns {string}
|
|
*/
|
|
_getTime: function (time) {
|
|
if( !time ){
|
|
return "<em class='ipsType_light ipsType_unbold ipsFaded'>" + ips.getString('select_time') + "</em>";
|
|
}
|
|
|
|
return time;
|
|
},
|
|
|
|
/**
|
|
* Returns the summary string for recurring events
|
|
*
|
|
* @returns {string}
|
|
*/
|
|
_getSummary: function () {
|
|
var type = this.scope.find('#elSelect_event_repeats').val();
|
|
var intervalString = '';
|
|
var endString = '';
|
|
|
|
// Build the 'interval' string
|
|
switch( type ){
|
|
case 'daily':
|
|
case 'monthly':
|
|
case 'yearly':
|
|
intervalString = this._buildString( type );
|
|
break;
|
|
case 'weekly':
|
|
intervalString = this._buildWeekly();
|
|
break;
|
|
}
|
|
|
|
// Build the 'end after' string
|
|
if( this.scope.find('#event_repeat_end_afterx').is(':checked') ){
|
|
var occurrences = parseInt( this.scope.find('input[name="event_dates[repeat_end_occurrences]"]').val() );
|
|
|
|
if( _.isNumber( occurrences ) && !_.isNaN( occurrences ) ){
|
|
endString = ips.pluralize( ips.getString( 'x_times' ), occurrences );
|
|
}
|
|
} else if( this.scope.find('#event_repeat_end_ondate').is(':checked') ){
|
|
var dateObj = ips.utils.time.getDateFromInput( this.scope.find('input[name="event_dates[repeat_end_date]"]') );
|
|
|
|
if( ips.utils.time.isValidDateObj( dateObj ) && dateObj.getFullYear() > 1900 ){ // > 1900 just so it doesn't start updating on year 19 etc.
|
|
endString = ips.getString('until', { date: ips.utils.time.localeDateString( dateObj, { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric' } ) } );
|
|
}
|
|
}
|
|
|
|
// Put it together
|
|
if( endString ){
|
|
return ips.getString( 'with_end', { interval: intervalString, endAfter: endString } );
|
|
} else {
|
|
return intervalString;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Builds a summary string for daily, monthly and yearly repeats
|
|
*
|
|
* @param {string} type The type of repeat
|
|
* @returns {string}
|
|
*/
|
|
_buildString: function ( type ) {
|
|
var val = parseInt( this.scope.find('#elSelect_event_repeat_freq').val() ) || 1;
|
|
return ips.pluralize( ips.getString( 'every_x', { period: ips.pluralize( ips.getString( 'x_' + type ), val ) } ), val );
|
|
},
|
|
|
|
/**
|
|
* Builds a summary string for weekly repeats
|
|
*
|
|
* @returns {string}
|
|
*/
|
|
_buildWeekly: function () {
|
|
var selectedDays = this.scope.find('[data-iCal]:checked');
|
|
var val = parseInt( this.scope.find('#elSelect_event_repeat_freq').val() ) || 1;
|
|
var weekString = '';
|
|
|
|
weekString = ips.pluralize( ips.getString( 'x_weekly' ), val );
|
|
|
|
// If no days are selected, we can bypass and finish now
|
|
if( !selectedDays.length ){
|
|
return weekString;
|
|
}
|
|
|
|
// Get full days
|
|
var fullDays = _.map( selectedDays, function (day, key) {
|
|
return ips.getString( $( day ).attr('data-iCal') );
|
|
});
|
|
|
|
// Build string
|
|
var dayString = '';
|
|
|
|
if( fullDays.length === 1 ){
|
|
dayString = ips.getString( 'one_day', { first: fullDays[0] } );
|
|
} else {
|
|
dayString = ips.getString( 'multiple_day', { days: fullDays.slice(0, -1).join(', '), last: fullDays[ fullDays.length - 1 ] });
|
|
}
|
|
|
|
return ips.getString( 'week_string', { week: weekString, days: dayString } );
|
|
},
|
|
|
|
/**
|
|
* Resizes the "Event End" grid box to be the same height as the start box
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
_resizeEndGrid: function () {
|
|
var height = 'auto';
|
|
|
|
if( !ips.utils.responsive.enabled() || !ips.utils.responsive.currentIs('phone') ){
|
|
height = this.scope.find('#elDateGrid_start').outerHeight() + 'px';
|
|
}
|
|
|
|
this.scope.find('#elDateGrid_end').css({
|
|
height: height
|
|
});
|
|
}
|
|
});
|
|
}(jQuery, _));]]></file>
|
|
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/venue" javascript_name="ips.venue.main.js" javascript_type="controller" javascript_version="102002" javascript_position="1000150"><![CDATA[/**
|
|
* Invision Community
|
|
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
|
*
|
|
* ips.venue.main.js - Venue main browsing controller
|
|
*
|
|
*/
|
|
;( function($, _, undefined){
|
|
"use strict";
|
|
|
|
ips.controller.register('calendar.front.venue.main', {
|
|
|
|
_ajaxObj: null,
|
|
|
|
initialize: function () {
|
|
this.on( 'click', '[data-action="changeView"]', this.changeView );
|
|
this.on( window, 'statechange', this.stateChange );
|
|
this.setup();
|
|
},
|
|
|
|
/**
|
|
* Controller setup method
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
setup: function () {
|
|
History.pushState( { controller: 'venueView' }, document.title, window.location.href );
|
|
},
|
|
|
|
/**
|
|
* Changes the calendar view dynamically
|
|
*
|
|
* @param {event} e Event object
|
|
* @returns {void}
|
|
*/
|
|
changeView: function (e) {
|
|
e.preventDefault();
|
|
|
|
// Load the url via ajax instead
|
|
var self = this;
|
|
var title = $( e.currentTarget ).attr('title');
|
|
var url = $( e.currentTarget ).attr('href');
|
|
|
|
History.pushState( { controller: 'venueView' }, title, url );
|
|
},
|
|
|
|
/**
|
|
* Event handler for history state changes
|
|
*
|
|
* @param {event} e Event object
|
|
* @returns {void}
|
|
*/
|
|
stateChange: function () {
|
|
var state = History.getState();
|
|
|
|
if( _.isUndefined( state.data.controller ) || state.data.controller != 'venueView' ) {
|
|
return;
|
|
}
|
|
|
|
// Track page view
|
|
ips.utils.analytics.trackPageView( state.url );
|
|
|
|
this._updateView( state.url, state.title )
|
|
},
|
|
|
|
/**
|
|
* Loads a new view
|
|
*
|
|
* @param {string} url URL to load
|
|
* @param {string} title New browser title
|
|
* @returns {void}
|
|
*/
|
|
_updateView: function (url, title) {
|
|
var self = this;
|
|
|
|
if( this._ajaxObj && _.isFunction( this._ajaxObj.abort ) ){
|
|
this._ajaxObj.abort();
|
|
}
|
|
|
|
this._setLoading( true );
|
|
|
|
this._ajaxObj = ips.getAjax()( url, {
|
|
showLoading: true
|
|
} )
|
|
.done( function (response) {
|
|
console.log( response );
|
|
self.scope.html( response );
|
|
|
|
$( document ).trigger( 'contentChange', [ self.scope ] );
|
|
|
|
History.pushState( { controller: 'venueView' }, title, url );
|
|
})
|
|
.always( function () {
|
|
self._setLoading( false );
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Toggles the loading state on the view
|
|
*
|
|
* @param {boolean} state Enable the loading state?
|
|
* @returns {void}
|
|
*/
|
|
_setLoading: function (state) {
|
|
if( state ){
|
|
this.scope.animate( { opacity: 0.6 }, 'fast' );
|
|
} else {
|
|
this.scope.animate( { opacity: 1 }, 'fast' );
|
|
}
|
|
}
|
|
});
|
|
}(jQuery, _));]]></file>
|
|
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.reminderButton.js" javascript_type="controller" javascript_version="102002" javascript_position="1000200"><![CDATA[/**
|
|
* Invision Community
|
|
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
|
*
|
|
* ips.calendar.reminderButton.js - Controller for event reminder button
|
|
*
|
|
* Author: Andrew Millne
|
|
*/
|
|
;( function($, _, undefined){
|
|
"use strict";
|
|
|
|
ips.controller.register('calendar.front.view.reminderButton', {
|
|
|
|
initialize: function () {
|
|
this.setup();
|
|
this.on( document, 'reminderItem', this.reminderItemChange );
|
|
},
|
|
|
|
setup: function () {
|
|
this._id = this.scope.attr('data-reminderID');
|
|
this._button = this.scope.find('[data-role="reminderButton"]');
|
|
},
|
|
|
|
/**
|
|
* Responds to events indicating the reminder status has changed
|
|
*
|
|
* @param {event} e Event object
|
|
* @param {object} data Event data object
|
|
* @returns {void}
|
|
*/
|
|
reminderItemChange: function (e, data) {
|
|
this._reloadButton();
|
|
},
|
|
|
|
/**
|
|
* Gets a new reminder button from the server and replaces the current one with the response
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
_reloadButton: function () {
|
|
// Show button as loading
|
|
this._button.addClass('ipsFaded ipsFaded_more');
|
|
|
|
var self = this;
|
|
var pos = ips.utils.position.getElemPosition( this._button );
|
|
var dims = ips.utils.position.getElemDims( this._button );
|
|
|
|
this.scope.append( ips.templates.render('calendar.reminder.loading') );
|
|
|
|
// Adjust sizing
|
|
this.scope
|
|
.css({
|
|
position: 'relative'
|
|
})
|
|
.find('.ipsLoading')
|
|
.css({
|
|
width: dims.outerWidth + 'px',
|
|
height: dims.outerHeight + 'px',
|
|
top: 0,
|
|
left: 0,
|
|
position: 'absolute',
|
|
zIndex: ips.ui.zIndex()
|
|
});
|
|
|
|
// Load new contents
|
|
ips.getAjax()( ips.getSetting('baseURL') + 'index.php?app=calendar&module=calendar&controller=event&do=reminderButton', {
|
|
data: _.extend({
|
|
id: this._id
|
|
}, ( this.scope.attr('data-buttonType') ) ? { button_type: this.scope.attr('data-buttonType') } : {} )
|
|
})
|
|
.done( function (response) {
|
|
self.scope.html( response );
|
|
$( document ).trigger( 'contentChange', [ self.scope ] );
|
|
})
|
|
.fail( function () {
|
|
self._button.removeClass('ipsFaded ipsFaded_more');
|
|
})
|
|
.always( function () {
|
|
self.scope.find('.ipsLoading').remove();
|
|
});
|
|
}
|
|
});
|
|
}(jQuery, _));]]></file>
|
|
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.reminderForm.js" javascript_type="controller" javascript_version="102002" javascript_position="1000200">/**
|
|
* Invision Community
|
|
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
|
*
|
|
* ips.calendar.reminderButton.js - Controller for reminder button
|
|
*
|
|
* Author: Andrew Millne
|
|
*/
|
|
;( function($, _, undefined){
|
|
"use strict";
|
|
|
|
ips.controller.register('calendar.front.view.reminderForm', {
|
|
|
|
initialize: function () {
|
|
this.on( 'submit', this.submitForm );
|
|
this.on( 'click', '[data-action="removereminder"]', this.removereminder );
|
|
this.setup();
|
|
},
|
|
|
|
/**
|
|
* Setup method
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
setup: function () {
|
|
},
|
|
|
|
/**
|
|
* Event handler for removing reminder
|
|
*
|
|
* @param {event} e Event object
|
|
* @returns {void}
|
|
*/
|
|
removereminder: function (e) {
|
|
e.preventDefault();
|
|
this._doRemindAction( $( e.currentTarget ).attr('href'), {}, true );
|
|
},
|
|
|
|
/**
|
|
* Event handler for submitting the reminder form
|
|
*
|
|
* @param {event} e Event object
|
|
* @returns {void}
|
|
*/
|
|
submitForm: function (e) {
|
|
e.preventDefault();
|
|
this._doRemindAction( this.scope.attr('action'), this.scope.serialize(), false );
|
|
},
|
|
|
|
/**
|
|
* Performs an ajax action.
|
|
*
|
|
* @param {string} url URL to call
|
|
* @param {object} data Object of data to include in the request
|
|
* @returns {void}
|
|
*/
|
|
_doRemindAction: function (url, data, removereminder ) {
|
|
var self = this;
|
|
var dims = ips.utils.position.getElemDims( this.scope.parent('div') );
|
|
|
|
// Set it to loading
|
|
this.scope
|
|
.hide()
|
|
.parent('div')
|
|
.css({
|
|
width: dims.outerWidth + 'px',
|
|
height: dims.outerHeight + 'px'
|
|
})
|
|
.addClass('ipsLoading');
|
|
|
|
// Update reminder preference via ajax
|
|
ips.getAjax()( url, {
|
|
data: data,
|
|
type: 'post'
|
|
})
|
|
.done( function (response, status, jqXHR) {
|
|
|
|
if( jqXHR.getAllResponseHeaders().indexOf('X-IPS-FormError: true') !== -1 || jqXHR.getAllResponseHeaders().indexOf('X-IPS-FormNoSubmit: true') !== -1 || jqXHR.getAllResponseHeaders().indexOf('x-ips-formerror: true') !== -1 || jqXHR.getAllResponseHeaders().indexOf('x-ips-formnosubmit: true') !== -1 ){
|
|
self.scope
|
|
.show()
|
|
.html( response )
|
|
.parent('div')
|
|
.removeClass('ipsLoading')
|
|
.css({
|
|
width: 'auto',
|
|
height: 'auto'
|
|
});
|
|
} else {
|
|
// Success, so trigger event to update button
|
|
self.trigger('reminderItem');
|
|
if( removereminder ) {
|
|
ips.ui.flashMsg.show(ips.getString('event_reminder_removed'));
|
|
}
|
|
else {
|
|
ips.ui.flashMsg.show(ips.getString('event_reminder_added'));
|
|
}
|
|
|
|
self.scope.parents('.ipsHovercard').remove();
|
|
}
|
|
})
|
|
.fail( function (jqXHR, textStatus, errorThrown) {
|
|
window.location = url;
|
|
})
|
|
.always( function () {
|
|
// If we're in a hovercard, remove it
|
|
});
|
|
}
|
|
});
|
|
}(jQuery, _));
|
|
</file>
|
|
<file javascript_app="calendar" javascript_location="front" javascript_path="templates" javascript_name="ips.calendar.templates.js" javascript_type="framework" javascript_version="102002" javascript_position="1000250"><![CDATA[/**
|
|
* Invision Community
|
|
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
|
*/
|
|
|
|
/* REMINDER BUTTON LOADING */
|
|
ips.templates.set('calendar.reminder.loading', " \
|
|
<div class='ipsLoading ipsLoading_tiny'></div>\
|
|
");]]></file>
|
|
<order app="global" path="/dev/js//framework/">templates
|
|
common/ips.loader.js
|
|
common/ui
|
|
common/utils
|
|
common
|
|
controllers</order>
|
|
<order app="global" path="/dev/js//library/">underscore
|
|
jquery
|
|
mustache
|
|
jstz
|
|
Debug.js
|
|
app.js</order>
|
|
<order app="global" path="/dev/js//library//jquery">jquery.js
|
|
jquery.history.js
|
|
jquery.transform.js</order>
|
|
<order app="global" path="/dev/js//library//linkify">linkify.min.js
|
|
linkify-jquery.min.js</order>
|
|
</javascript>
|