merge
This commit is contained in:
commit
046a724272
4209 changed files with 1186656 additions and 0 deletions
545
www/analytics/plugins/CoreHome/javascripts/calendar.js
Normal file
545
www/analytics/plugins/CoreHome/javascripts/calendar.js
Normal file
|
|
@ -0,0 +1,545 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function ($) {
|
||||
|
||||
Date.prototype.getWeek = function () {
|
||||
var onejan = new Date(this.getFullYear(), 0, 1), // needed for getDay()
|
||||
|
||||
// use UTC times since getTime() can differ based on user's timezone
|
||||
onejan_utc = Date.UTC(this.getFullYear(), 0, 1),
|
||||
this_utc = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()),
|
||||
|
||||
daysSinceYearStart = (this_utc - onejan_utc) / 86400000; // constant is millisecs in one day
|
||||
|
||||
return Math.ceil((daysSinceYearStart + onejan.getDay()) / 7);
|
||||
};
|
||||
|
||||
var currentYear, currentMonth, currentDay, currentDate, currentWeek;
|
||||
|
||||
function setCurrentDate(dateStr) {
|
||||
var splitDate = dateStr.split("-");
|
||||
currentYear = splitDate[0];
|
||||
currentMonth = splitDate[1] - 1;
|
||||
currentDay = splitDate[2];
|
||||
currentDate = new Date(currentYear, currentMonth, currentDay);
|
||||
currentWeek = currentDate.getWeek();
|
||||
}
|
||||
|
||||
if(!piwik.currentDateString) {
|
||||
// eg. Login form
|
||||
return;
|
||||
}
|
||||
setCurrentDate(piwik.currentDateString);
|
||||
|
||||
var todayDate = new Date;
|
||||
var todayMonth = todayDate.getMonth();
|
||||
var todayYear = todayDate.getFullYear();
|
||||
var todayDay = todayDate.getDate();
|
||||
|
||||
// min/max date for picker
|
||||
var piwikMinDate = new Date(piwik.minDateYear, piwik.minDateMonth - 1, piwik.minDateDay),
|
||||
piwikMaxDate = new Date(piwik.maxDateYear, piwik.maxDateMonth - 1, piwik.maxDateDay);
|
||||
|
||||
// we start w/ the current period
|
||||
var selectedPeriod = piwik.period;
|
||||
|
||||
function isDateInCurrentPeriod(date) {
|
||||
// if the selected period isn't the current period, don't highlight any dates
|
||||
if (selectedPeriod != piwik.period) {
|
||||
return [true, ''];
|
||||
}
|
||||
|
||||
var valid = false;
|
||||
|
||||
var dateMonth = date.getMonth();
|
||||
var dateYear = date.getFullYear();
|
||||
var dateDay = date.getDate();
|
||||
|
||||
// we don't color dates in the future
|
||||
if (dateMonth == todayMonth
|
||||
&& dateYear == todayYear
|
||||
&& dateDay > todayDay
|
||||
) {
|
||||
return [true, ''];
|
||||
}
|
||||
|
||||
// we don't color dates before the minimum date
|
||||
if (dateYear < piwik.minDateYear
|
||||
|| ( dateYear == piwik.minDateYear
|
||||
&&
|
||||
(
|
||||
(dateMonth == piwik.minDateMonth - 1
|
||||
&& dateDay < piwik.minDateDay)
|
||||
|| (dateMonth < piwik.minDateMonth - 1)
|
||||
)
|
||||
)
|
||||
) {
|
||||
return [true, ''];
|
||||
}
|
||||
|
||||
// we color all day of the month for the same year for the month period
|
||||
if (piwik.period == "month"
|
||||
&& dateMonth == currentMonth
|
||||
&& dateYear == currentYear
|
||||
) {
|
||||
valid = true;
|
||||
}
|
||||
// we color all day of the year for the year period
|
||||
else if (piwik.period == "year"
|
||||
&& dateYear == currentYear
|
||||
) {
|
||||
valid = true;
|
||||
}
|
||||
else if (piwik.period == "week"
|
||||
&& date.getWeek() == currentWeek
|
||||
&& dateYear == currentYear
|
||||
) {
|
||||
valid = true;
|
||||
}
|
||||
else if (piwik.period == "day"
|
||||
&& dateDay == currentDay
|
||||
&& dateMonth == currentMonth
|
||||
&& dateYear == currentYear
|
||||
) {
|
||||
valid = true;
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
return [true, 'ui-datepicker-current-period'];
|
||||
}
|
||||
|
||||
return [true, ''];
|
||||
}
|
||||
|
||||
piwik.getBaseDatePickerOptions = function (defaultDate) {
|
||||
return {
|
||||
showOtherMonths: false,
|
||||
dateFormat: 'yy-mm-dd',
|
||||
firstDay: 1,
|
||||
minDate: piwikMinDate,
|
||||
maxDate: piwikMaxDate,
|
||||
prevText: "",
|
||||
nextText: "",
|
||||
currentText: "",
|
||||
defaultDate: defaultDate,
|
||||
changeMonth: true,
|
||||
changeYear: true,
|
||||
stepMonths: 1,
|
||||
// jquery-ui-i18n 1.7.2 lacks some translations, so we use our own
|
||||
dayNamesMin: [
|
||||
_pk_translate('General_DaySu'),
|
||||
_pk_translate('General_DayMo'),
|
||||
_pk_translate('General_DayTu'),
|
||||
_pk_translate('General_DayWe'),
|
||||
_pk_translate('General_DayTh'),
|
||||
_pk_translate('General_DayFr'),
|
||||
_pk_translate('General_DaySa')],
|
||||
dayNamesShort: [
|
||||
_pk_translate('General_ShortDay_7'), // start with sunday
|
||||
_pk_translate('General_ShortDay_1'),
|
||||
_pk_translate('General_ShortDay_2'),
|
||||
_pk_translate('General_ShortDay_3'),
|
||||
_pk_translate('General_ShortDay_4'),
|
||||
_pk_translate('General_ShortDay_5'),
|
||||
_pk_translate('General_ShortDay_6')],
|
||||
dayNames: [
|
||||
_pk_translate('General_LongDay_7'), // start with sunday
|
||||
_pk_translate('General_LongDay_1'),
|
||||
_pk_translate('General_LongDay_2'),
|
||||
_pk_translate('General_LongDay_3'),
|
||||
_pk_translate('General_LongDay_4'),
|
||||
_pk_translate('General_LongDay_5'),
|
||||
_pk_translate('General_LongDay_6')],
|
||||
monthNamesShort: [
|
||||
_pk_translate('General_ShortMonth_1'),
|
||||
_pk_translate('General_ShortMonth_2'),
|
||||
_pk_translate('General_ShortMonth_3'),
|
||||
_pk_translate('General_ShortMonth_4'),
|
||||
_pk_translate('General_ShortMonth_5'),
|
||||
_pk_translate('General_ShortMonth_6'),
|
||||
_pk_translate('General_ShortMonth_7'),
|
||||
_pk_translate('General_ShortMonth_8'),
|
||||
_pk_translate('General_ShortMonth_9'),
|
||||
_pk_translate('General_ShortMonth_10'),
|
||||
_pk_translate('General_ShortMonth_11'),
|
||||
_pk_translate('General_ShortMonth_12')],
|
||||
monthNames: [
|
||||
_pk_translate('General_LongMonth_1'),
|
||||
_pk_translate('General_LongMonth_2'),
|
||||
_pk_translate('General_LongMonth_3'),
|
||||
_pk_translate('General_LongMonth_4'),
|
||||
_pk_translate('General_LongMonth_5'),
|
||||
_pk_translate('General_LongMonth_6'),
|
||||
_pk_translate('General_LongMonth_7'),
|
||||
_pk_translate('General_LongMonth_8'),
|
||||
_pk_translate('General_LongMonth_9'),
|
||||
_pk_translate('General_LongMonth_10'),
|
||||
_pk_translate('General_LongMonth_11'),
|
||||
_pk_translate('General_LongMonth_12')]
|
||||
};
|
||||
};
|
||||
|
||||
var updateDate;
|
||||
|
||||
function getDatePickerOptions() {
|
||||
var result = piwik.getBaseDatePickerOptions(currentDate);
|
||||
result.beforeShowDay = isDateInCurrentPeriod;
|
||||
result.stepMonths = selectedPeriod == 'year' ? 12 : 1;
|
||||
result.onSelect = function () { updateDate.apply(this, arguments); };
|
||||
return result;
|
||||
}
|
||||
|
||||
$(function () {
|
||||
|
||||
var datepickerElem = $('#datepicker').datepicker(getDatePickerOptions()),
|
||||
periodLabels = $('#periodString').find('.period-type label'),
|
||||
periodTooltip = $('#periodString').find('.period-click-tooltip').html();
|
||||
|
||||
var toggleWhitespaceHighlighting = function (klass, toggleTop, toggleBottom) {
|
||||
var viewedYear = $('.ui-datepicker-year', datepickerElem).val(),
|
||||
viewedMonth = +$('.ui-datepicker-month', datepickerElem).val(), // convert to int w/ '+'
|
||||
firstOfViewedMonth = new Date(viewedYear, viewedMonth, 1),
|
||||
lastOfViewedMonth = new Date(viewedYear, viewedMonth + 1, 0);
|
||||
|
||||
// only highlight dates between piwik.minDate... & piwik.maxDate...
|
||||
// we select the cells to highlight by checking whether the first & last of the
|
||||
// currently viewed month are within the min/max dates.
|
||||
if (firstOfViewedMonth >= piwikMinDate) {
|
||||
$('tbody>tr:first-child td.ui-datepicker-other-month', datepickerElem).toggleClass(klass, toggleTop);
|
||||
}
|
||||
if (lastOfViewedMonth < piwikMaxDate) {
|
||||
$('tbody>tr:last-child td.ui-datepicker-other-month', datepickerElem).toggleClass(klass, toggleBottom);
|
||||
}
|
||||
};
|
||||
|
||||
// 'this' is the table cell
|
||||
var highlightCurrentPeriod = function () {
|
||||
switch (selectedPeriod) {
|
||||
case 'day':
|
||||
// highlight this link
|
||||
$('a', $(this)).addClass('ui-state-hover');
|
||||
break;
|
||||
case 'week':
|
||||
var row = $(this).parent();
|
||||
|
||||
// highlight parent row (the week)
|
||||
$('a', row).addClass('ui-state-hover');
|
||||
|
||||
// toggle whitespace if week goes into previous or next month. we check if week is on
|
||||
// top or bottom row.
|
||||
var toggleTop = row.is(':first-child'),
|
||||
toggleBottom = row.is(':last-child');
|
||||
toggleWhitespaceHighlighting('ui-state-hover', toggleTop, toggleBottom);
|
||||
break;
|
||||
case 'month':
|
||||
// highlight all parent rows (the month)
|
||||
$('a', $(this).parent().parent()).addClass('ui-state-hover');
|
||||
break;
|
||||
case 'year':
|
||||
// highlight table (month + whitespace)
|
||||
$('a', $(this).parent().parent()).addClass('ui-state-hover');
|
||||
toggleWhitespaceHighlighting('ui-state-hover', true, true);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
var unhighlightAllDates = function () {
|
||||
// make sure nothing is highlighted
|
||||
$('.ui-state-active,.ui-state-hover', datepickerElem).removeClass('ui-state-active ui-state-hover');
|
||||
|
||||
// color whitespace
|
||||
if (piwik.period == 'year') {
|
||||
var viewedYear = $('.ui-datepicker-year', datepickerElem).val(),
|
||||
toggle = selectedPeriod == 'year' && currentYear == viewedYear;
|
||||
toggleWhitespaceHighlighting('ui-datepicker-current-period', toggle, toggle);
|
||||
}
|
||||
else if (piwik.period == 'week') {
|
||||
var toggleTop = $('tr:first-child a', datepickerElem).parent().hasClass('ui-datepicker-current-period'),
|
||||
toggleBottom = $('tr:last-child a', datepickerElem).parent().hasClass('ui-datepicker-current-period');
|
||||
toggleWhitespaceHighlighting('ui-datepicker-current-period', toggleTop, toggleBottom);
|
||||
}
|
||||
};
|
||||
|
||||
updateDate = function (dateText) {
|
||||
piwikHelper.showAjaxLoading('ajaxLoadingCalendar');
|
||||
|
||||
// select new dates in calendar
|
||||
setCurrentDate(dateText);
|
||||
piwik.period = selectedPeriod;
|
||||
|
||||
// make sure it's called after jquery-ui is done, otherwise everything we do will
|
||||
// be undone.
|
||||
setTimeout(unhighlightAllDates, 1);
|
||||
|
||||
datepickerElem.datepicker('refresh');
|
||||
|
||||
// Let broadcast do its job:
|
||||
// It will replace date value to both search query and hash and load the new page.
|
||||
broadcast.propagateNewPage('date=' + dateText + '&period=' + selectedPeriod);
|
||||
};
|
||||
|
||||
var toggleMonthDropdown = function (disable) {
|
||||
if (typeof disable === 'undefined') {
|
||||
disable = selectedPeriod == 'year';
|
||||
}
|
||||
|
||||
// enable/disable month dropdown based on period == year
|
||||
$('.ui-datepicker-month', datepickerElem).attr('disabled', disable);
|
||||
};
|
||||
|
||||
var togglePeriodPickers = function (showSingle) {
|
||||
$('#periodString').find('.period-date').toggle(showSingle);
|
||||
$('#periodString').find('.period-range').toggle(!showSingle);
|
||||
$('#calendarRangeApply').toggle(!showSingle);
|
||||
};
|
||||
|
||||
//
|
||||
// setup datepicker
|
||||
//
|
||||
|
||||
unhighlightAllDates();
|
||||
|
||||
//
|
||||
// hook up event slots
|
||||
//
|
||||
|
||||
// highlight current period when mouse enters date
|
||||
datepickerElem.on('mouseenter', 'tbody td', function () {
|
||||
if ($(this).hasClass('ui-state-hover')) // if already highlighted, do nothing
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// unhighlight if cell is disabled/blank, unless the period is year
|
||||
if ($(this).hasClass('ui-state-disabled') && selectedPeriod != 'year') {
|
||||
unhighlightAllDates();
|
||||
|
||||
// if period is week, then highlight the current week
|
||||
if (selectedPeriod == 'week') {
|
||||
highlightCurrentPeriod.call(this);
|
||||
}
|
||||
}
|
||||
else {
|
||||
highlightCurrentPeriod.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
// make sure cell stays highlighted when mouse leaves cell (overrides jquery-ui behavior)
|
||||
datepickerElem.on('mouseleave', 'tbody td', function () {
|
||||
$('a', this).addClass('ui-state-hover');
|
||||
});
|
||||
|
||||
// unhighlight everything when mouse leaves table body (can't do event on tbody, for some reason
|
||||
// that fails, so we do two events, one on the table & one on thead)
|
||||
datepickerElem.on('mouseleave', 'table', unhighlightAllDates)
|
||||
.on('mouseenter', 'thead', unhighlightAllDates);
|
||||
|
||||
// make sure whitespace is clickable when the period makes it appropriate
|
||||
datepickerElem.on('click', 'tbody td.ui-datepicker-other-month', function () {
|
||||
if ($(this).hasClass('ui-state-hover')) {
|
||||
var row = $(this).parent(), tbody = row.parent();
|
||||
|
||||
if (row.is(':first-child')) {
|
||||
// click on first of the month
|
||||
$('a', tbody).first().click();
|
||||
}
|
||||
else {
|
||||
// click on last of month
|
||||
$('a', tbody).last().click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Hack to get around firefox bug. When double clicking a label in firefox, the 'click'
|
||||
// event of its associated input will not be fired twice. We want to change the period
|
||||
// if clicking the select period's label OR input, so we catch the click event on the
|
||||
// label & the input.
|
||||
var reloading = false;
|
||||
var changePeriodOnClick = function (periodInput) {
|
||||
if (reloading) // if a click event resulted in reloading, don't reload again
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var url = periodInput.val(),
|
||||
period = broadcast.getValueFromUrl('period', url);
|
||||
|
||||
// if clicking on the selected period, change the period but not the date
|
||||
if (selectedPeriod == period && selectedPeriod != 'range') {
|
||||
// only reload if current period is different from selected
|
||||
if (piwik.period != selectedPeriod && !reloading) {
|
||||
reloading = true;
|
||||
selectedPeriod = period;
|
||||
updateDate(piwik.currentDateString);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
$("#otherPeriods").find("label").on('click', function (e) {
|
||||
var id = $(e.target).attr('for');
|
||||
changePeriodOnClick($('#' + id));
|
||||
});
|
||||
|
||||
// when non-range period is clicked, change the period & refresh the date picker
|
||||
$("#otherPeriods").find("input").on('click', function (e) {
|
||||
var request_URL = $(e.target).val(),
|
||||
period = broadcast.getValueFromUrl('period', request_URL),
|
||||
lastPeriod = selectedPeriod;
|
||||
|
||||
if (changePeriodOnClick($(e.target))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// switch the selected period
|
||||
selectedPeriod = period;
|
||||
|
||||
// remove tooltips from the period inputs
|
||||
periodLabels.each(function () { $(this).attr('title', '').removeClass('selected-period-label'); });
|
||||
|
||||
// range periods are handled in an event handler below
|
||||
if (period == 'range') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// set the tooltip of the current period
|
||||
if (period != piwik.period) // don't add tooltip for current period
|
||||
{
|
||||
$(this).parent().find('label[for=period_id_' + period + ']')
|
||||
.attr('title', periodTooltip).addClass('selected-period-label');
|
||||
}
|
||||
|
||||
// toggle the right selector controls (show period selector datepicker & hide 'apply range' button)
|
||||
togglePeriodPickers(true);
|
||||
|
||||
// set months step to 12 for year period (or set back to 1 if leaving year period)
|
||||
if (selectedPeriod == 'year' || lastPeriod == 'year') {
|
||||
// setting stepMonths will change the month in view back to the selected date. to avoid
|
||||
// we set the selected date to the month in view.
|
||||
var currentMonth = $('.ui-datepicker-month', datepickerElem).val(),
|
||||
currentYear = $('.ui-datepicker-year', datepickerElem).val();
|
||||
|
||||
datepickerElem
|
||||
.datepicker('option', 'stepMonths', selectedPeriod == 'year' ? 12 : 1)
|
||||
.datepicker('setDate', new Date(currentYear, currentMonth));
|
||||
}
|
||||
|
||||
datepickerElem.datepicker('refresh'); // must be last datepicker call, otherwise cells get highlighted
|
||||
|
||||
unhighlightAllDates();
|
||||
toggleMonthDropdown();
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// clicking left/right re-enables the month dropdown, so we disable it again
|
||||
$(datepickerElem).on('click', '.ui-datepicker-next,.ui-datepicker-prev', function () {
|
||||
unhighlightAllDates(); // make sure today's date isn't highlighted & toggle extra year highlighting
|
||||
toggleMonthDropdown(selectedPeriod == 'year');
|
||||
});
|
||||
|
||||
// reset date/period when opening calendar
|
||||
$("#periodString").on('click', "#date,.calendar-icon", function () {
|
||||
var periodMore = $("#periodMore").toggle();
|
||||
if (periodMore.is(":visible")) {
|
||||
periodMore.find(".ui-state-highlight").removeClass('ui-state-highlight');
|
||||
}
|
||||
});
|
||||
|
||||
$('body').on('click', function(e) {
|
||||
var target = $(e.target);
|
||||
if (target.closest('html').length && !target.closest('#periodString').length && !target.is('option') && $("#periodMore").is(":visible")) {
|
||||
$("#periodMore").hide();
|
||||
}
|
||||
});
|
||||
|
||||
function onDateRangeSelect(dateText, inst) {
|
||||
var toOrFrom = inst.id == 'calendarFrom' ? 'From' : 'To';
|
||||
$('#inputCalendar' + toOrFrom).val(dateText);
|
||||
}
|
||||
|
||||
// this will trigger to change only the period value on search query and hash string.
|
||||
$("#period_id_range").on('click', function (e) {
|
||||
togglePeriodPickers(false);
|
||||
|
||||
var options = getDatePickerOptions();
|
||||
|
||||
// Custom Date range callback
|
||||
options.onSelect = onDateRangeSelect;
|
||||
// Do not highlight the period
|
||||
options.beforeShowDay = '';
|
||||
// Create both calendars
|
||||
options.defaultDate = piwik.startDateString;
|
||||
$('#calendarFrom').datepicker(options).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', piwik.startDateString));
|
||||
|
||||
// Technically we should trigger the onSelect event on the calendar, but I couldn't find how to do that
|
||||
// So calling the onSelect bind function manually...
|
||||
//$('#calendarFrom').trigger('dateSelected'); // or onSelect
|
||||
onDateRangeSelect(piwik.startDateString, { "id": "calendarFrom" });
|
||||
|
||||
// Same code for the other calendar
|
||||
options.defaultDate = piwik.endDateString;
|
||||
$('#calendarTo').datepicker(options).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', piwik.endDateString));
|
||||
onDateRangeSelect(piwik.endDateString, { "id": "calendarTo" });
|
||||
|
||||
|
||||
// If not called, the first date appears light brown instead of dark brown
|
||||
$('.ui-state-hover').removeClass('ui-state-hover');
|
||||
|
||||
// Apply date range button will reload the page with the selected range
|
||||
$('#calendarRangeApply')
|
||||
.on('click', function () {
|
||||
var request_URL = $(e.target).val();
|
||||
var dateFrom = $('#inputCalendarFrom').val(),
|
||||
dateTo = $('#inputCalendarTo').val(),
|
||||
oDateFrom = $.datepicker.parseDate('yy-mm-dd', dateFrom),
|
||||
oDateTo = $.datepicker.parseDate('yy-mm-dd', dateTo);
|
||||
|
||||
if (!isValidDate(oDateFrom)
|
||||
|| !isValidDate(oDateTo)
|
||||
|| oDateFrom > oDateTo) {
|
||||
$('#alert').find('h2').text(_pk_translate('General_InvalidDateRange'));
|
||||
piwikHelper.modalConfirm('#alert', {});
|
||||
return false;
|
||||
}
|
||||
piwikHelper.showAjaxLoading('ajaxLoadingCalendar');
|
||||
broadcast.propagateNewPage('period=range&date=' + dateFrom + ',' + dateTo);
|
||||
})
|
||||
.show();
|
||||
|
||||
|
||||
// Bind the input fields to update the calendar's date when date is manually changed
|
||||
$('#inputCalendarFrom, #inputCalendarTo')
|
||||
.keyup(function (e) {
|
||||
var fromOrTo = this.id == 'inputCalendarFrom' ? 'From' : 'To';
|
||||
var dateInput = $(this).val();
|
||||
try {
|
||||
var newDate = $.datepicker.parseDate('yy-mm-dd', dateInput);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
$("#calendar" + fromOrTo).datepicker("setDate", newDate);
|
||||
if (e.keyCode == 13) {
|
||||
$('#calendarRangeApply').click();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
});
|
||||
function isValidDate(d) {
|
||||
if (Object.prototype.toString.call(d) !== "[object Date]")
|
||||
return false;
|
||||
return !isNaN(d.getTime());
|
||||
}
|
||||
|
||||
if (piwik.period == 'range') {
|
||||
$("#period_id_range").click();
|
||||
}
|
||||
});
|
||||
|
||||
}(jQuery));
|
||||
Loading…
Add table
Add a link
Reference in a new issue