' +
'
' + $scope.message + '
' +
'
' +
'
' +
'
' +
'
' +
'
' + Translator.getTranslation('modal_attach_message') + '
' +
'
' +
'
' + Translator.getTranslation('modal_attach_error_notavailable') + '
' +
'
' +
'' + Translator.getTranslation('modal_attach_error_size') + ' ' +
'' + Translator.getTranslation('modal_attach_error_format') + ' ' +
'
' +
'
' +
'
' +
'
' +
'
' + Translator.getTranslation('modal_loading') + ': {{attach.progress}}%
' +
'
'
;
}
return strret;
}
$scope.getHeader = function () {
var strret = '';
if (typeof $scope.type !== 'undefined' && $scope.type.toLowerCase() === 'error') {
strret = (typeof $scope.showclose != 'undefined' && $scope.showclose() ? '
× ' : '')
+ '
' + Translator.getTranslation('modal_error') + ' ';
}
else if (typeof $scope.type !== 'undefined' && $scope.type.toLowerCase() === 'warning') {
strret = (typeof $scope.showclose != 'undefined' && $scope.showclose() ? '
× ' : '');
}
else if (typeof $scope.type !== 'undefined' && ($scope.type.toLowerCase() === 'question')) {
strret = (typeof $scope.showclose != 'undefined' && $scope.showclose() ? '
× ' : '')
+ '
' + $scope.title + ' ';
}
return strret;
}
$scope.getFooter = function () {
var strret = '';
if (typeof $scope.type !== 'undefined' && ($scope.type.toLowerCase() === 'error')) {
strret = '
' + Translator.getTranslation('modal_close') + '
';
}
if (typeof $scope.type !== 'undefined' && ($scope.type.toLowerCase() === 'warning')) {
strret = '
' + Translator.getTranslation('modal_continue') + '
';
}
if (typeof $scope.type !== 'undefined' && $scope.type.toLowerCase() === 'question') {
strret = '
' + Translator.getTranslation('modal_yes') + ' ' + Translator.getTranslation('modal_no') + '
';
}
return strret;
}
$scope.isFirst = function () {
return $scope.defaultbtn === '1';
}
$scope.isSecond = function () {
return $scope.defaultbtn === '2';
}
$scope.isError = function () {
return (typeof $scope.type !== 'undefined' && $scope.type.toLowerCase() === 'error');
}
$scope.isLoading = function () {
return ((typeof $scope.type === 'undefined' || $scope.type.toLowerCase() === 'loading') &&
(typeof $scope.contentid === 'undefined' || $scope.contentid === ''));
}
$scope.isWarning = function () {
return (typeof $scope.type !== 'undefined' && $scope.type.toLowerCase() === 'warning');
}
$scope.isTranscluded = function () {
return (typeof $scope.type !== 'undefined' && $scope.type.toLowerCase() === 'transcluded');
}
$scope.isQuestion = function () {
return (typeof $scope.type !== 'undefined' && $scope.type.toLowerCase() === 'question');
}
$scope.isInfo = function () {
return (typeof $scope.type !== 'undefined' && $scope.type.toLowerCase() === 'info');
}
$scope.isDrop = function () {
return (typeof $scope.type !== 'undefined' && $scope.type.toLowerCase() === 'attach');
}
$scope.errorResult = function () {
if (typeof $scope.resultmethod !== 'undefined' && $scope.resultmethod !== null) {
$scope.resultmethod();
} else {
$scope.show = false;
}
}
$scope.closeAttach = function () {
$scope.show = false;
if ($scope.attach !== 'undefined' && $scope.attach !== null) {
$scope.attach = null;
}
}
$scope.disableKeyBoard = function () {
return (typeof $scope.type !== 'undefined' && ($scope.type.toLowerCase() === 'error' || $scope.type.toLowerCase() === 'warning'));
}
$scope.questionResult = function (result) {
if (typeof $scope.resultmethod !== 'undefined' && $scope.resultmethod !== null) {
$scope.resultmethod(result);
}
}
}
};
});
//directiva para evitar que se marque un formulario como $dirty
ngSharedDirectives.directive('noDirty', function () {
return {
require: 'ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$setDirty = angular.noop;
}
}
});
// html filter (render text as html)
ngSharedDirectives.filter('trusted', ['$sce', function ($sce) {
return function (text) {
return $sce.trustAsHtml(text);
};
}]);
ngSharedDirectives.filter('formatLineEndings', ['$sce', function ($sce) {
return function (text) {
if (typeof text !== "undefined" && text != null) {
text = '
' + text;
text = text.replace(/--/g, "");
text = text.replace(/\\r?\\n|\\r|\\n/g, "
");
text = text.replace(/
<\/p>/g, "");
text = text + '
';
return $sce.trustAsHtml(text);
}
return text;
};
}]);
//Foco en campo de formulario
ngSharedDirectives.directive('focusMe', function ($timeout) {
return {
scope: { trigger: '=focusMe' },
link: function (scope, element) {
scope.$watch('trigger', function (value) {
if (value === true) {
//console.log('trigger',value);
$timeout(function() {
element[0].focus();
}, 200);
}
});
}
};
});
ngSharedDirectives.directive('selectOnClick', ['$window', function ($window) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.on('click', function () {
if (!$window.getSelection().toString()) {
// Required for mobile Safari
this.setSelectionRange(0, this.value.length)
}
});
}
};
}]);
ngSharedDirectives.filter('range', function () {
return function (input, from, to) {
to = parseInt(to, 10);
from = parseInt(from, 10);
for (var i = from; i < to; i++) {
input.push(i);
}
return input;
};
});
ngSharedDirectives.filter('notEmpty', function () {
return function (input) {
return typeof input !== 'undefined' && input !== null && input !== '';
};
});
ngSharedDirectives.filter('isEmpty', function () {
return function (input) {
return typeof input === 'undefined' || input === null || input === '';
};
});
ngSharedDirectives.filter('trim', function () {
return function (value) {
if (!angular.isString(value)) {
return value;
}
return value.replace(/^\s+|\s+$/g, ''); // you could use .trim, but it's not going to work in IE<9
};
});
ngSharedDirectives.filter('UTC', function ($filter) {
return function (date, format) {
var tmp = new Date(date);
var dt = new Date(tmp.getTime() + (tmp.getTimezoneOffset() * 60000));
if (typeof format !== 'undefined' && format !== null && format !== '')
return $filter('date')(dt, format);
return dt;
};
});
ngSharedDirectives.filter('dateLE', function ($filter) {
return function (date1, date2, onlyDate) {
var r = false;
if (date1 != undefined && date2 != undefined) {
if (typeof onlyDate == undefined) onlyDate = false;
var d1 = new Date(date1.getTime());
var d2 = new Date(date2.getTime());
if (onlyDate) {
d1.setHours(0, 0, 0, 0);
d2.setHours(0, 0, 0, 0);
}
r = d1.getTime() <= d2.getTime();
}
return r;
};
});
ngSharedDirectives.filter('replace', function ($filter) {
return function (str) {
if (typeof str != 'undefined' && str != null) {
var newstr = str;
if (arguments.length <= 1)
return newstr;
var replaceElems = Array.prototype.slice.call(arguments);
replaceElems.splice(0, 1);
for (i in replaceElems) {
newstr = newstr.replace(RegExp('\\{' + i + '\\}', 'gi'), replaceElems[i]);
}
return newstr;
}
};
});
ngSharedDirectives.filter("formatCurrency", function ($filter) {
return function (amount, mask) {
if (typeof mask != 'undefined' && mask != null && typeof amount != 'undefined' && amount != null) {
return mask.replace(/\s/g, "").replace(/\{(\d+)\}/g, function (match, capture) {
return $filter('number')(amount, 2);
});
};
};
});
ngSharedDirectives.directive('stCalendar', function (shApi, $filter) {
return {
restrict: 'E',
require: ['^?form'],
scope: {
'date': '=',
'dateInputName': '@',
'toDate': '=',
'toDateInputName': '@',
'dateCalendarCenter': '=',
'culture': '@',
'dateFormat': '@',
'minDate': '=',
'maxDate': '=',
'placeholder': '@',
'scheduling': '=',
'isInline': '=',
'isReadOnly': '=',
'clear': '=',
'range': '=',
'rangeSeparator': '@',
'mainClass': '@',
'iconClass': '@',
'label': '@',
'headerTitle': '@',
'isOpen': '=',
'disabled': '=',
'viewMode': '@',
'right': '@',
'left': '=',
'rightIconIfLeftTrue': '@',
},
link: function (scope, elem, attrs, ctrls) {
var hasForm = false;
if (ctrls[0] != null) {
hasForm = true;
scope.form = ctrls[0];
}
var defaultCulture = "en";
var defaultViewMode = "days";
var fullScheduling = null;
scope.autoClose = true;
scope.isOpen = false;
scope.errorList = [];
scope.required = angular.isDefined(attrs.required);
scope.deleteBtn = angular.isDefined(attrs.deleteBtn);
if (scope.disabled === undefined) scope.disabled = false;
if (scope.isInline === undefined) scope.isInline = false;
if (scope.dateFormat === undefined) scope.dateFormat = "";
if (scope.placeholder === undefined) scope.placeholder = "";
if (scope.deleteBtn === undefined) scope.deleteBtn = false;
if (scope.minDate === undefined || scope.minDate === null)
scope.minDate = "";
else if (!angular.isDate(scope.minDate))
scope.minDate = new Date(scope.minDate);
if (scope.maxDate === undefined || scope.maxDate === null)
scope.maxDate = "";
else if (!angular.isDate(scope.maxDate))
scope.maxDate = new Date(scope.maxDate);
if (scope.range === undefined) scope.range = false;
if (scope.rangeSeparator === undefined) scope.rangeSeparator = '-';
if (scope.isReadOnly === undefined) scope.isReadOnly = false;
if (scope.clear === undefined) scope.clear = false;
if (scope.scheduling !== undefined) fullScheduling = scope.scheduling;
if (scope.viewMode === undefined) scope.viewMode = defaultViewMode;
if (scope.culture === undefined || scope.culture.length < 2)
scope.culture = defaultCulture;
else
scope.culture = scope.culture.substr(0, 2);
var divCalendar = $(elem).find(".calendar-div")[0];
var onRender = function (date, cellType) {
if (cellType == 'day') {
var day = date.getDate();
if (fullScheduling !== null) {
var currentDate = formatDate(date.getDate(), date.getMonth(), date.getFullYear());
if (fullScheduling[currentDate] != undefined) {
if (!fullScheduling[currentDate].IsSoldOut) {
var priceFormatted = $filter('formatCurrency')(fullScheduling[currentDate].FromPrice, fullScheduling[currentDate].CurrencyMask);
return {
html: '
' + day + '
' + priceFormatted + '
'
}
} else {
return {
disabled: true,
html: '
' + day + '
'
}
}
} else {
return {
disabled: true,
html: '
' + day + '
',
}
}
}
else {
//Standard format:
return {
html: '
' + day + '
',
}
}
}
};
var formatDate = function (day, month, year) {
if (day < 10) {
day = "0" + day;
}
if ((month + 1) < 10) {
month = "0" + (month + 1);
} else {
month = month + 1;
}
date = year + "-" + month + "-" + day + "T00:00:00Z";
return date;
};
//Load datepicker
var calendar = $(divCalendar).datepicker({
inline: scope.isInline,
range: scope.range,
language: scope.culture,
autoClose: scope.autoClose,
classes: 'new-datepicker',
dateFormat: scope.dateFormat,
minDate: scope.minDate,
maxDate: scope.maxDate,
view: scope.viewMode,
onRenderCell: function (date, cellType) {
return onRender(date, cellType);
},
onSelect: function (formattedDate, date, inst) {
if (scope.range) {
if (date.length == 2) {
var datesFormatted = formattedDate.split(",");
scope.date = date[0];
scope.toDate = date[1];
scope.dateText = datesFormatted[0];
scope.toDateText = datesFormatted[1];
if (hasForm) {
scope.form[scope.dateInputName].$setDirty();
}
close.trigger('click');
}
}
else {
if (date != "" && !isNaN(date.getTime()) ) {
lastDate = date;
scope.date = lastDate;
scope.dateText = formattedDate;
if (hasForm) {
scope.form[scope.dateInputName].$setValidity('pattern', true);
scope.form[scope.dateInputName].$setDirty();
}
close.trigger('click');
}
}
},
});
var calendarData = calendar.data('datepicker');
calendar.hide();
if (scope.dateCalendarCenter !== undefined && scope.dateCalendarCenter !== null) {
var dateCalendarCenter = new Date(scope.dateCalendarCenter)
if (angular.isDate(dateCalendarCenter)) {
calendarData.date = dateCalendarCenter;
}
}
scope.$watch('minDate', function (newVal, oldVal) {
if (newVal != oldVal) {
var changeMinDate = '';
if (newVal !== undefined && newVal != null) {
var daux;
if (angular.isDate(newVal)) {
daux = newVal;
}
else {
daux = new Date(newVal);
}
changeMinDate = daux;
}
calendarData.update('minDate', changeMinDate);
}
});
scope.$watch('maxDate', function (newVal, oldVal) {
if (newVal != oldVal) {
var changeMaxDate = '';
if (newVal !== undefined && newVal != null) {
var daux;
if (angular.isDate(newVal)) {
daux = newVal;
}
else {
daux = new Date(newVal);
}
changeMaxDate = daux;
}
calendarData.update('maxDate', changeMaxDate);
}
});
scope.$watch('scheduling', function (newVal, oldVal) {
if (newVal != oldVal) {
if (angular.isObject(newVal) && newVal !== undefined && newVal != null) {
fullScheduling = newVal;
}
else
fullScheduling = null;
//Reload template
calendarData.update({});
}
});
var close = $('
');
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-dropdown-container');
var returnbutton = $(elem[0]).find('.js-return');
$(document).mouseup(function (e) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
if (scope.isOpen) {
e.preventDefault();
close.trigger('click');
}
}
});
$(document).ready(function (e) {
close.click(function (e) {
calendar.hide();
scope.isOpen = false;
shApi.fullWindow(false);
//TODO: esto??
scope.$applyAsync();
});
button.click(function (e) {
if (!scope.isOpen) {
if (!scope.disabled) {
calendar.show();
scope.$apply(function () {
scope.isOpen = true;
});
shApi.fullWindow(true);
}
} else {
close.trigger('click');
}
});
returnbutton.click(function (e) {
close.trigger('click');
});
if (scope.date !== null && scope.date !== undefined) {
if (angular.isDate(scope.date))
calendarData.selectDate(scope.date);
else
calendarData.selectDate(new Date(scope.date));
}
if (scope.range && scope.toDate !== null && scope.toDate !== undefined) {
if (angular.isDate(scope.toDate))
calendarData.selectDate(scope.toDate);
else
calendarData.selectDate(new Date(scope.toDate));
}
scope.$watch('date', function (newVal, oldVal) {
if (newVal === undefined || newVal === null) {
calendarData.clear();
scope.dateText = "";
}
else if (angular.isDate(newVal) && angular.isDate(oldVal)) {
if (newVal.getTime() !== oldVal.getTime() && (calendarData.selectedDates[0] === undefined || newVal.getTime() !== calendarData.selectedDates[0].getTime()))
calendarData.selectDate(newVal);
}
else if (newVal !== oldVal && (calendarData.selectedDates[0] === undefined || newVal.getTime() !== calendarData.selectedDates[0].getTime())) {
if (angular.isDate(newVal))
calendarData.selectDate(newVal);
else
calendarData.selectDate(new Date(newVal));
}
});
if (scope.range) {
scope.$watch('toDate', function (newVal, oldVal) {
if (newVal === undefined || newVal === null) {
calendarData.clear();
scope.toDateText = "";
}
else if (angular.isDate(newVal) && angular.isDate(oldVal)) {
if (newVal.getTime() !== oldVal.getTime() && (calendarData.selectedDates[1] === undefined || newVal.getTime() !== calendarData.selectedDates[1].getTime()))
calendarData.selectDate(newVal);
}
else if (newVal !== oldVal && (calendarData.selectedDates[1] === undefined || newVal.getTime() !== calendarData.selectedDates[1].getTime())) {
calendarData.selectDate(newVal);
}
});
}
if (!scope.isReadOnly) {
var inputDate = $(elem).find('input')[0];
$(inputDate).on("change", function (event) {
var newDate = shApi.parseStringToDate(inputDate.value, scope.dateFormat);
if (newDate != null && angular.isDate(newDate) && !isNaN(newDate.getTime())) {
if (hasForm)
scope.form[scope.dateInputName].$setValidity('pattern', true);
if (newDate > calendarData.minDate && calendarData.maxDate > newDate) {
calendarData.selectDate(newDate);
calendarData.date = newDate;
}
else if (calendarData.minDate > newDate) {
calendarData.selectDate(calendarData.minDate);
calendarData.date = calendarData.minDate;
}
else if (newDate > calendarData.maxDate) {
calendarData.selectDate(calendarData.maxDate);
calendarData.date = calendarData.maxDate;
}
}
else {
if (hasForm)
scope.form[scope.dateInputName].$setValidity('pattern', false);
//TODO: esto??
scope.$applyAsync();
}
});
}
if (scope.deleteBtn) {
scope.deleteDate = function (e) {
e.preventDefault();
scope.date = null;
if (scope.range) {
scope.toDate = null;
}
}
}
})
},
controller: function ($scope) {
},
templateUrl: '/Scripts/app/Modules/stCalendarTemplate.html'
};
});
ngSharedDirectives.directive('stTimepicker', function (shApi) {
return {
restrict: 'E',
require: ['^?form'],
scope: {
'time': '=',
'timeInputName': '@',
'minTime': '=',
'maxTime': '=',
'stepMinutes': '@',
'placeholder': '@',
'mainClass': '@',
'iconClass': '@',
'label': '@',
'headerTitle': '@',
'applymsg': '@',
'isOpen': '=',
'disabled': '=',
'allowClear': '=',
'clearmsg': '@',
'right': '@',
'alone': '=',
},
link: function (scope, elem, attrs, ctrls) {
var hasForm = false;
if (ctrls[0] != null) {
hasForm = true;
scope.form = ctrls[0];
}
scope.isOpen = false;
scope.required = angular.isDefined(attrs.required)
var normalizeMinutes = function () {
var minutes = scope.time.getMinutes();
if (minutes != 0) {
var minutesMultiplier = Math.round(minutes / scope.stepMinutes);
scope.time.setMinutes(minutesMultiplier * scope.stepMinutes);
}
};
if (scope.disabled === undefined) scope.disabled = false;
if (scope.allowClear == undefined) scope.allowClear = false;
if (scope.placeholder === undefined) scope.placeholder = "";
if (scope.headerTitle === undefined) scope.headerTitle = "";
if (scope.applymsg === undefined) scope.applymsg = "";
if (scope.stepMinutes === undefined) scope.stepMinutes = 1;
if (scope.time !== undefined && angular.isDate(scope.time))
normalizeMinutes();
var container = $(elem).find('.js-dropdown-container');
var inputElement = $(elem).find("input")[0];
var button = $(elem).find('.js-button-selector');
var applyBtn = $(elem).find('.js-save-button');
var returnBtn = $(elem).find('.js-return');
var clearBtn = $(elem).find('.js-clear-button');
returnBtn.click(function (e) {
closeAndSaveTimePicker();
});
applyBtn.click(function (e) {
closeAndSaveTimePicker();
});
clearBtn.click(function (e) {
if (scope.allowClear) {
closeAndClearTimePicker();
}
});
var formatTime = function (date) {
var hour = date.getHours().toString();
if (hour.length == 1) hour = "0" + hour;
var minute = date.getMinutes().toString();
if (minute.length == 1) minute = "0" + minute;
var timeFormatted = hour + ":" + minute;
return timeFormatted;
};
var closeAndSaveTimePicker = function () {
$(inputElement).closeTimepicker();
container.addClass('hidden');
scope.isOpen = false;
var newTime;
if (scope.time !== undefined && angular.isDate(scope.time))
newTime = new Date(scope.time.getTime());
else
newTime = new Date();
var timeSplitted = inputElement.value.split(':');
newTime.setHours(parseInt(timeSplitted[0]), parseInt(timeSplitted[1]));
scope.time = newTime;
scope.$apply();
};
var closeAndClearTimePicker = function () {
$(inputElement).closeTimepicker();
container.addClass('hidden');
scope.isOpen = false;
scope.time = null;
scope.timeFormatted = null;
scope.$apply();
}
var openTimePicker = function () {
if (!scope.disabled) {
$(inputElement).timepicker({
minuteStep: parseInt(scope.stepMinutes),
headerText: scope.headerTitle,
applyText: scope.applymsg
});
if (scope.alone == true) {
var newTime;
if (scope.time !== undefined && angular.isDate(scope.time))
newTime = new Date(scope.time.getTime());
else
newTime = new Date();
scope.time = newTime;
scope.$apply();
var timeSplitted = inputElement.value.split(':');
newTime.setHours(parseInt(timeSplitted[0]), parseInt(timeSplitted[1]));
scope.$apply();
}
$(inputElement).showTimepicker();
scope.$apply(function () {
scope.isOpen = true;
});
var timepicker = $(elem).find('.timepicker');
var timepickerContainer = $(elem).find('#timepickerContainer');
$(timepicker).appendTo(timepickerContainer);
container.removeClass('hidden');
}
};
$(document).mouseup(function (e) {
if (scope.isOpen) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
e.preventDefault();
closeAndSaveTimePicker();
}
}
});
$(document).ready(function (e) {
button.click(function (e) {
if (!scope.isOpen) {
openTimePicker();
} else {
closeAndSaveTimePicker();
}
});
});
scope.$watch('time', function (newVal, oldVal) {
if (angular.isDate(newVal)) {
normalizeMinutes();
var timeFormatted = formatTime(newVal);
if (timeFormatted !== scope.timeFormatted)
scope.timeFormatted = timeFormatted;
}
else {
scope.timeFormatted = null;
}
});
},
controller: function ($scope) {
},
templateUrl: '/Scripts/app/Modules/stTimepickerTemplate.html'
};
});
ngSharedDirectives.directive('stAlerts', function ($timeout, $compile) {
var count = 0;
return {
replace: false,
scope: { stAlerts: '=' },
link: function (scope, element, attrs, ctrls) {
var elem = element;
scope.internalControl = scope.stAlerts || {}
scope.internalControl.showSuccess = function (msg) {
alertstyle = "alerts alerts-style-success";
addAlert(msg, alertstyle);
};
scope.internalControl.showWarning = function (msg) {
alertstyle = "alerts alerts-style-warning";
addAlert(msg, alertstyle);
};
scope.internalControl.showError = function (msg) {
alertstyle = "alerts alerts-style-error";
addAlert(msg, alertstyle);
};
function addAlert(msg, alertstyle) {
var id = "alert" + (++count);
elem.append($compile('
' + msg + '×
')(scope));
var elemdiv = elem.children().last();
$timeout(function () { deleteAlert(elemdiv); }, 5000);
};
function deleteAlert(elemdiv) {
elemdiv.remove();
};
scope.deleteFromClick = function (e) {
deleteAlert(e.target.parentElement);
};
},
};
});
ngSharedDirectives.directive('stSlider', ['$parse', function ($parse) {
return {
replace: true,
require: ['ngModel'],
template: '
',
link: function (scope, element, attrs, ctrls) {
var ctrl = ctrls[0];
var title = "Slider";
var key = null;
var val = null;
var compareField = null;
var initIsDefined = false;
var parentForm = element.parent().controller('form');
var modelGetter = $parse(attrs['ngModel']);
// This returns a function that lets us set the value of the ng-model binding expression:
var modelSetter = modelGetter.assign;
if (angular.isDefined(attrs.stSliderTitle)) {
var auxt = scope.$eval(attrs.stSliderTitle);
if (auxt === undefined)
title = attrs.stSliderTitle;
else
title = auxt;
}
if (angular.isDefined(attrs.stSliderValue)) {
var auxv = scope.$eval(attrs.stSliderValue);
if (auxv === undefined)
val = attrs.stSliderValue;
else
val = auxv;
}
if (angular.isDefined(attrs.stSliderCompareField)) {
var auxc = attrs.stSliderCompareField;
if (auxc === undefined)
compareField = attrs.stCompareField;
else
compareField = auxc;
}
if (angular.isDefined(attrs.stSliderKey)) {
var auxk = scope.$eval(attrs.stSliderKey);
if (auxk === undefined)
key = attrs.stSliderKey;
else
key = auxk;
}
var auxs = scope.$eval(attrs.stSliderSource);
if (auxs === undefined)
src = attrs.stSliderSource;
else
src = auxs;
scope.$watch(attrs.stSliderSource, function (newValue, oldValue) {
if (newValue != oldValue) {
src = newValue;
var parsed = parseItems(newValue);
element.stslider('setSource', parsed);
if (pendingToSet != null) {
var aux = pendingToSet;
pendingToSet = null;
setValueInSlider(aux);
}
}
});
var parseItems = function (src) {
var itemsval = [];
if (val != null) {
var tempval = "";
for (var i = 0; i < src.length; i++) {
tempval = src[i][val];
itemsval.push(tempval);
}
}
else {
itemsval = src;
}
return itemsval;
}
element.stslider({
source: parseItems(src),
messages: {
Title: title,
},
change: function (event, ui) {
if (isUpdating) return;
var getval = element.stslider('getValue');
var newviewval = "";
if (val != null && key != null) {
for (var i = 0; i < src.length; i++) {
if (getval == src[i][val]) {
newviewval = src[i][key];
break;
}
}
}
else if (val != null && key == null) {
for (var i = 0; i < src.length; i++) {
if (getval == src[i][val]) {
newviewval = src[i];
break;
}
}
}
else {
newviewval = getval;
}
ctrl.$setViewValue(newviewval);
ctrl.$setTouched();
}
});
var pendingToSet = null;
var isUpdating = false;
ctrl.$formatters.unshift(function (keyvalue) {
if (src.length == 0 && keyvalue != undefined) pendingToSet = keyvalue;
else {
setValueInSlider(keyvalue);
}
});
var setValueInSlider = function (keyvalue) {
var newvalue = 0;
var isPristine = true;
if (ctrl.$dirty === true)
isPristine = false;
if (compareField != null) {
for (var i = 0; i < src.length; i++) {
if (keyvalue[compareField] == src[i][compareField]) {
newvalue = src[i][val];
break;
}
}
}
else if (key != null) {
for (var i = 0; i < src.length; i++) {
if (keyvalue == src[i][key]) {
newvalue = src[i][val];
break;
}
}
}
else {
newvalue = keyvalue;
}
isUpdating = true;
element.stslider('setValue', newvalue);
isUpdating = false;
if (isPristine === true) {
ctrl.$setPristine();
ctrl.$setUntouched();
parentForm.$setPristine();
}
};
}
};
}]);
//TODO: Revisar
ngSharedDirectives.directive('stPhone', [function () {
return {
require: ['ngModel'],
restrict: 'A',
scope: {
'ngModel': '=',
'stPhoneCode': '=',
'stCountryCode': '=',
},
link: function (scope, elem, attrs, ctrls) {
var opened;
var myCtrls = ctrls[0];
var initialCtry = '';
var settingCode = false;
if (angular.isDefined(attrs.stPhoneCode)) {
var auxv = scope.$eval(attrs.stPhoneCode);
if (auxv === undefined)
initialCtry = scope.stPhoneCode;
else
initialCtry = auxv;
}
$(document).ready(function () {
//si ya está cargado eliminamos el anterior porque no funciona muy bien el plugin
//de js cuando hay más de uno en pantalla y cuando se clona.
if (elem.attr('yetloaded') == 'true') {
elem.parent().find('.flag-container').remove();
elem.unwrap();
}
if (initialCtry == undefined || initialCtry == null || initialCtry == '') {
elem.intlTelInput({ initialCountry: '' });
} else {
elem.intlTelInput({ initialCountry: initialCtry });
}
scope.stPhoneCode = elem.intlTelInput("getSelectedCountryData").dialCode;
initialCtry = scope.stPhoneCode; //inicialización por defecto
if (elem.attr('yetloaded') == undefined)
elem.attr('yetloaded', 'true');
});
elem.on('countrychange', function (e, countryData) {
if (!settingCode) {
scope.$apply(function () {
settingCode = true;
scope.stPhoneCode = countryData.dialCode;
scope.stCountryCode = countryData.iso2;
});
settingCode = false;
//elem.focus();
//elem.blur();
}
});
elem.on('dropDown', function (e) {
if (!opened) {
scope.$apply(function () {
scope.ngModel = null;
});
}
opened = !opened;
});
scope.$watch('stPhoneCode', function (newVal, oldVal) {
if (newVal != oldVal && !settingCode) {
//Si no está definido establecer el valor por defecto
settingCode = true;
if (newVal == undefined || newVal == null || newVal == '') {
elem.intlTelInput("setCountry", initialCtry);
}
else {
elem.intlTelInput("setCountry", newVal);
}
settingCode = false;
scope.stPhoneCode = elem.intlTelInput("getSelectedCountryData").dialCode;
scope.stCountryCode = elem.intlTelInput("getSelectedCountryData").iso2;
}
});
myCtrls.$parsers.unshift(function (inputValue) {
if (!opened) {
return inputValue;
} else {
myCtrls.$setViewValue(null);
return null;
}
});
}
}
}
]);
ngSharedDirectives.directive('stCurrencySelector', ['$cookies', function ($cookies) {
return {
require: ['ngModel'],
link: function (scope, element, attrs, ctrls) {
var modelCtrl = ctrls[0];
var key = null;
if (angular.isDefined(attrs.stCurrencySelectorKey)) {
var auxv = scope.$eval(attrs.stCurrencySelectorKey);
if (auxv === undefined)
key = attrs.stCurrencySelectorKey;
else
key = auxv;
}
var val = null;
if (angular.isDefined(attrs.stCurrencySelectorValue)) {
var auxw = scope.$eval(attrs.stCurrencySelectorValue);
if (auxw === undefined)
val = attrs.stCurrencySelectorValue;
else
val = auxw;
}
var imp = null;
if (angular.isDefined(attrs.stCurrencySelectorImportance)) {
var auxt = scope.$eval(attrs.stCurrencySelectorImportance);
if (auxt === undefined)
imp = attrs.stCurrencySelectorImportance;
else
imp = auxt;
}
var cha = null;
if (angular.isDefined(attrs.stCurrencySelectorChange)) {
var auxy = scope.$eval(attrs.stCurrencySelectorChange);
if (auxy === undefined)
cha = attrs.stCurrencySelectorChange;
else
cha = auxy;
}
var opt1 = null;
if (angular.isDefined(attrs.stCurrencySelectorOptions1)) {
opt1 = attrs.stCurrencySelectorOptions1;
}
var opt2 = null;
if (angular.isDefined(attrs.stCurrencySelectorOptions2)) {
opt2 = attrs.stCurrencySelectorOptions2;
}
var nam = null;
if (angular.isDefined(attrs.stCurrencySelectorName)) {
var aux3 = scope.$eval(attrs.stCurrencySelectorName);
if (aux3 === undefined)
nam = attrs.stCurrencySelectorName;
else
nam = aux3;
}
var src = null;
var auxs = scope.$eval(attrs.stCurrencySelectorSource);
if (auxs === undefined)
src = attrs.stCurrencySelectorSource;
else
src = auxs;
var mainCurrenciesLabel = opt1;
element.append($('
'));
$.each(src, function (index, object) {
if (object[imp]) {
element.append($('', {
value: key == null ? object : object[key],
text: key == null ? object : object[val] + " " + object[key],
}));
}
});
var otherCurrenciesLabel = opt2;
element.append($(' '));
$.each(src, function (index, object) {
if (!object[imp]) {
element.append($('', {
value: key == null ? object : object[key],
text: key == null ? object : object[val] + " " + object[key],
}));
}
});
element.append($(' '));
modelCtrl.$parsers.unshift(function (inputValue) {
if (!imp) {
return inputValue;
}
else {
for (var i = 0; i < src.length; i++) {
if (src[i][key] == inputValue) {
return src[i];
}
}
}
});
modelCtrl.$formatters.unshift(function (keyvalue) {
var newvalue = null;
if (key != null) //Con campo key
{
if (keyvalue != undefined) {
for (var i = 0; i < src.length; i++) {
if (keyvalue[key] == src[i][key]) {
newvalue = src[i][key];
}
}
}
}
else {
newvalue = keyvalue;
}
modelCtrl.$setViewValue(newvalue);
element.val(newvalue);
return newvalue;
});
},
};
}]);
ngSharedDirectives.directive('ngEsc', function ($document) {
return {
restrict: 'A',
link: function (scope, element, attr) {
var handler = function (evt) {
var which = evt.which;
if (which == 27) {
scope.$apply(attr.ngEsc);
evt.preventDefault();
evt.stopPropagation();
}
};
//var cleanup = function () {
// $document.off('keydown keypress keyup', handler);
//};
$document.on('keydown keypress keyup', handler);
//element.on('$destroy', cleanup);
}
}
});
ngSharedDirectives.value('THROTTLE_MILLISECONDS', null);
ngSharedDirectives.directive('infiniteScroll', [
'$rootScope', '$window', '$timeout', 'THROTTLE_MILLISECONDS', function ($rootScope, $window, $timeout, THROTTLE_MILLISECONDS) {
return {
scope: {
infiniteScroll: '&',
infiniteScrollContainer: '=',
infiniteScrollDistance: '=',
infiniteScrollDisabled: '='
},
link: function (scope, elem, attrs) {
var changeContainer, checkWhenEnabled, container, handleInfiniteScrollContainer, handleInfiniteScrollDisabled, handleInfiniteScrollDistance, handler, immediateCheck, scrollDistance, scrollEnabled, throttle;
$window = angular.element($window);
scrollDistance = null;
scrollEnabled = null;
checkWhenEnabled = null;
container = null;
immediateCheck = true;
handler = function () {
var containerBottom, elementBottom, remaining, shouldScroll;
if (container === $window) {
containerBottom = container.height() + container.scrollTop();
elementBottom = elem.offset().top + elem.height();
} else {
containerBottom = container.height();
elementBottom = elem.offset().top - container.offset().top + elem.height();
}
remaining = elementBottom - containerBottom;
shouldScroll = remaining <= container.height() * scrollDistance + 1;
if (shouldScroll && scrollEnabled) {
return scope.infiniteScroll();
} else if (shouldScroll) {
return checkWhenEnabled = true;
}
};
throttle = function (func, wait) {
var later, previous, timeout;
timeout = null;
previous = 0;
later = function () {
var context;
previous = new Date().getTime();
$timeout.cancel(timeout);
timeout = null;
func.call();
return context = null;
};
return function () {
var now, remaining;
now = new Date().getTime();
remaining = wait - (now - previous);
if (remaining <= 0) {
clearTimeout(timeout);
$timeout.cancel(timeout);
timeout = null;
previous = now;
return func.call();
} else {
if (!timeout) {
return timeout = $timeout(later, remaining);
}
}
};
};
if (THROTTLE_MILLISECONDS != null) {
handler = throttle(handler, THROTTLE_MILLISECONDS);
}
scope.$on('$destroy', function () {
return container.off('scroll', handler);
});
handleInfiniteScrollDistance = function (v) {
return scrollDistance = parseInt(v, 10) || 0;
};
scope.$watch('infiniteScrollDistance', handleInfiniteScrollDistance);
handleInfiniteScrollDistance(scope.infiniteScrollDistance);
handleInfiniteScrollDisabled = function (v) {
scrollEnabled = !v;
if (scrollEnabled && checkWhenEnabled) {
checkWhenEnabled = false;
return handler();
}
};
scope.$watch('infiniteScrollDisabled', handleInfiniteScrollDisabled);
handleInfiniteScrollDisabled(scope.infiniteScrollDisabled);
changeContainer = function (newContainer) {
if (container != null) {
container.off('scroll', handler);
}
container = newContainer;
if (newContainer != null) {
return container.on('scroll', handler);
}
};
changeContainer($window);
handleInfiniteScrollContainer = function (newContainer) {
if ((!(newContainer != null)) || newContainer.length === 0) {
return;
}
newContainer = angular.element(newContainer);
if (newContainer != null) {
return changeContainer(newContainer);
} else {
throw new Exception("invalid infinite-scroll-container attribute.");
}
};
scope.$watch('infiniteScrollContainer', handleInfiniteScrollContainer);
handleInfiniteScrollContainer(scope.infiniteScrollContainer || []);
if (attrs.infiniteScrollParent != null) {
changeContainer(angular.element(elem.parent()));
}
if (attrs.infiniteScrollImmediateCheck != null) {
immediateCheck = scope.$eval(attrs.infiniteScrollImmediateCheck);
}
return $timeout((function () {
if (immediateCheck) {
return handler();
}
}), 0);
}
};
}
]);
ngSharedDirectives.directive('stRadiobuttonSelector', function () {
return {
restrict: 'E',
scope: {
model: '=',
options: '=',
mainoption: '@',
firstoption: '@',
alternativeoption: '@',
optionValue: '=',
mainClass: '@',
isOpen: '=',
disabled: '=',
},
link: function (scope, elem, attrs, ctrls) {
if (scope.fixed === undefined) scope.fixed = false;
if (scope.disabled === undefined) scope.disabled = false;
scope.isOpen = false;
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-dropdown-container');
var close = $(elem[0]).find('.js-save-button');
$(document).mouseup(function (e) {
if (!scope.fixed) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
if (!container.hasClass('hidden')) {
e.preventDefault();
close.trigger('click');
}
}
}
});
$(document).ready(function (e) {
button.click(function (e) {
if (container.hasClass('hidden')) {
if (!scope.disabled) {
container.removeClass('hidden');
scope.$apply(function () {
scope.isOpen = true;
});
}
}
else {
e.preventDefault();
close.trigger('click');
}
})
close.click(function (e) {
container.addClass('hidden');
scope.$apply(function () {
scope.isOpen = false;
});
});
});
/*TODO:Esto debe ser generico*/
scope.$watch('optionValue', function (newVal, oldVal) {
if (newVal != undefined && newVal != null) {
if (newVal) {
scope.selectedOption = 'option2';
scope.mainoption = scope.alternativeoption;
}
else {
scope.selectedOption = 'option1';
scope.mainoption = scope.firstoption;
}
}
else {
scope.mainoption = null;
scope.selectedOption = null;
}
});
scope.$watch('selectedOption', function (newVal, oldVal) {
if (newVal != oldVal) {
if (newVal == 'option2') {
scope.mainoption = scope.alternativeoption;
scope.optionValue = true;
}
else if (newVal == 'option1') {
scope.mainoption = scope.firstoption;
scope.optionValue = false;
}
container.addClass('hidden');
scope.isOpen = false;
}
});
},
templateUrl: '/Scripts/app/Modules/stRadiobuttonSelector.html'
};
});
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
ngSharedDirectives.directive('keyEnter', function () {
return function (scope, element, attrs) {
element.bind("keydown keypress", function (event) {
if (event.which === 13) {
scope.$apply(function () {
scope.$eval(attrs.keyEnter, { 'event': event });
});
event.preventDefault();
}
});
};
});
ngSharedDirectives.directive('starRating', [function () {
return {
restrict: 'A',
replace: true,
scope: {
starRating: '='
},
link:
function (scope, element, attrs) {
scope.$watch("starRating", function (newValue, oldValue) {
var val = parseFloat(newValue);
var size = Math.max(0, (Math.min(5, val))) * 16;
element[0].style.width = size + 'px';
element[0].style.backgroundPositionY = '0px';
});
}
}
}]);
ngSharedDirectives.directive('bsTooltip', function () {
return {
link: function (scope, element, attrs) {
$(element).hover(function () {
// on mouseenter
$(element).tooltip('show');
}, function () {
// on mouseleave
$(element).tooltip('hide');
});
}
};
});
ngSharedDirectives.directive('labelField', function () {
return {
restrict: 'AE',
link: function ($scope, element, attrs) {
$scope.$watch(attrs['ngModel'], function (newValue) {
if (newValue && typeof newValue[attrs['labelField']] != 'undefined') {
element[0].value = newValue[attrs['labelField']];
}
})
}
}
});
ngSharedDirectives.directive('bindHtmlCompile', ['$compile', function ($compile) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
scope.$watch(function () {
return scope.$eval(attrs.bindHtmlCompile);
}, function (value) {
// In case value is a TrustedValueHolderType, sometimes it
// needs to be explicitly called into a string in order to
// get the HTML string.
element.html(value && value.toString());
// If scope is provided use it, otherwise use parent scope
var compileScope = scope;
if (attrs.bindHtmlScope) {
compileScope = scope.$eval(attrs.bindHtmlScope);
}
$compile(element.contents())(compileScope);
});
}
};
}]);
ngSharedDirectives.factory('Cards', [function () {
var defaultFormat = /(\d{1,4})/g;
var defaultInputFormat = /(?:^|\s)(\d{4})$/;
var cards = [
{
type: 'maestro',
pattern: /^(5018|5020|5038|6304|6759|676[1-3])/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [12, 13, 14, 15, 16, 17, 18, 19],
cvcLength: [3],
luhn: true
}, {
type: 'dinersclub',
pattern: /^(36|38|30[0-5])/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [14],
cvcLength: [3],
luhn: true
}, {
type: 'laser',
pattern: /^(6706|6771|6709)/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [16, 17, 18, 19],
cvcLength: [3],
luhn: true
}, {
type: 'jcb',
pattern: /^35/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [16],
cvcLength: [3],
luhn: true
}, {
type: 'unionpay',
pattern: /^62/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [16, 17, 18, 19],
cvcLength: [3],
luhn: false
}, {
type: 'discover',
pattern: /^(6011|65|64[4-9]|622)/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [16],
cvcLength: [3],
luhn: true
}, {
type: 'mastercard',
pattern: /^5[1-5]/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [16],
cvcLength: [3],
luhn: true
}, {
type: 'amex',
pattern: /^3[47]/,
format: /(\d{1,4})(\d{1,6})?(\d{1,5})?/,
inputFormat: /^(\d{4}|\d{4}\s\d{6})$/,
length: [15],
cvcLength: [3, 4],
luhn: true
}, {
type: 'visa',
pattern: /^4/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [13, 14, 15, 16],
cvcLength: [3],
luhn: true
}
];
var _fromNumber = function (num) {
var card, i, len;
num = (num + '').replace(/\D/g, '');
for (i = 0, len = cards.length; i < len; i++) {
card = cards[i];
if (card.pattern.test(num)) {
return card;
}
}
}
var _fromType = function (type) {
var card, i, len;
for (i = 0, len = cards.length; i < len; i++) {
card = cards[i];
if (card.type === type) {
return card;
}
}
};
return {
fromNumber: function (val) { return _fromNumber(val) },
fromType: function (val) { return _fromType(val) },
defaultFormat: function () { return defaultFormat; },
defaultInputFormat: function () { return defaultInputFormat; }
}
}])
.factory('_Format', ['Cards', '$filter', function (Cards, $filter) {
var _formats = {}
var _hasTextSelected = function ($target) {
var ref;
if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== $target.prop('selectionEnd')) {
return true;
}
if (typeof document !== "undefined" && document !== null ? (ref = document.selection) != null ? typeof ref.createRange === "function" ? ref.createRange().text : void 0 : void 0 : void 0) {
return true;
}
return false;
};
// card formatting
var _formatCardNumber = function (e) {
var $target, card, digit, length, re, upperLength, value;
digit = String.fromCharCode(e.which);
$target = angular.element(e.currentTarget);
value = $target.val();
card = Cards.fromNumber(value + digit);
length = (value.replace(/\D/g, '') + digit).length;
upperLength = 16;
if (card) {
upperLength = card.length[card.length.length - 1];
}
if (length >= upperLength) {
return;
}
if (!/^\d+$/.test(digit) && !e.meta && e.keyCode >= 46) {
e.preventDefault();
return;
}
if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== value.length) {
return;
}
re = Cards.defaultInputFormat();
if (card) {
re = card.inputFormat;
}
if (re.test(value)) {
e.preventDefault();
return $target.val(value + ' ' + digit);
} else if (re.test(value + digit)) {
e.preventDefault();
return $target.val(value + digit + ' ');
}
};
var _restrictCardNumber = function (e) {
var $target, card, digit, value;
$target = angular.element(e.currentTarget);
digit = String.fromCharCode(e.which);
if (!/^\d+$/.test(digit)) {
return;
}
if (_hasTextSelected($target)) {
return;
}
value = ($target.val() + digit).replace(/\D/g, '');
card = Cards.fromNumber(value);
if (card) {
if (!(value.length <= card.length[card.length.length - 1])) {
e.preventDefault();
}
} else {
if (!(value.length <= 16)) {
e.preventDefault();
}
}
};
var _formatBackCardNumber = function (e) {
var $target, value;
$target = angular.element(e.currentTarget);
value = $target.val();
if (e.meta) {
return;
}
if (e.which !== 8) {
return;
}
if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== value.length) {
return;
}
if (/\d\s$/.test(value) && !e.meta && e.keyCode >= 46) {
e.preventDefault();
return $target.val(value.replace(/\d\s$/, ''));
} else if (/\s\d?$/.test(value)) {
e.preventDefault();
return $target.val(value.replace(/\s\d?$/, ''));
}
};
var _getFormattedCardNumber = function (num) {
var card, groups, upperLength, ref;
card = Cards.fromNumber(num);
if (!card) {
return num;
}
upperLength = card.length[card.length.length - 1];
num = num.replace(/\D/g, '');
num = num.slice(0, +upperLength + 1 || 9e9);
if (card.format.global) {
return (ref = num.match(card.format)) != null ? ref.join(' ') : void 0;
} else {
groups = card.format.exec(num);
if (groups != null) {
groups.shift();
}
return groups != null ? groups.join(' ') : void 0;
}
};
var _reFormatCardNumber = function (e) {
return setTimeout(function () {
var $target, value;
$target = angular.element(e.target);
value = $target.val();
value = _getFormattedCardNumber(value);
return $target.val(value);
});
};
var _parseCardNumber = function (value) {
return value != null ? value.replace(/\s/g, '') : value;
};
_formats['card'] = function (elem, ctrl) {
elem.bind('keypress', _restrictCardNumber);
elem.bind('keypress', _formatCardNumber);
elem.bind('keydown', _formatBackCardNumber);
elem.bind('paste', _reFormatCardNumber);
ctrl.$parsers.push(_parseCardNumber);
ctrl.$formatters.push(_getFormattedCardNumber);
}
// cvc
_formatCVC = function (e) {
$target = angular.element(e.currentTarget);
digit = String.fromCharCode(e.which);
if (!/^\d+$/.test(digit) && !e.meta && e.keyCode >= 46) {
e.preventDefault();
return;
}
val = $target.val() + digit;
if (val.length <= 4) {
return;
} else {
e.preventDefault();
return;
}
}
_formats['cvc'] = function (elem) {
elem.bind('keypress', _formatCVC)
}
return function (type, elem, ctrl) {
if (!_formats[type]) {
types = Object.keys(_formats);
errstr = 'Unknown type for formatting: "' + type + '". ';
errstr += 'Should be one of: "' + types.join('", "') + '"';
throw errstr;
}
return _formats[type](elem, ctrl);
}
}])
.directive('paymentsFormat', ['$window', '_Format', function ($window, _Format) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, elem, attr, ctrl) {
_Format(attr.paymentsFormat, elem, ctrl);
}
}
}])
.factory('_Validate', ['Cards', '$parse', function (Cards, $parse) {
var __indexOf = [].indexOf || function (item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }
var _luhnCheck = function (num) {
var digit, digits, odd, sum, i, len;
odd = true;
sum = 0;
digits = (num + '').split('').reverse();
for (i = 0, len = digits.length; i < len; i++) {
digit = digits[i];
digit = parseInt(digit, 10);
if ((odd = !odd)) {
digit *= 2;
}
if (digit > 9) {
digit -= 9;
}
sum += digit;
}
return sum % 10 === 0;
};
var _validators = {}
_validators['cvc'] = function (cvc, ctrl, scope, attr) {
var ref, ref1;
// valid if empty - let ng-required handle empty
if (cvc == null || cvc.length == 0) return true;
if (!/^\d+$/.test(cvc)) {
return false;
}
var type;
if (attr.paymentsTypeModel) {
var typeModel = $parse(attr.paymentsTypeModel);
type = typeModel(scope);
}
if (type) {
return ref = cvc.length, __indexOf.call((ref1 = Cards.fromType(type)) != null ? ref1.cvcLength : void 0, ref) >= 0;
} else {
return cvc.length >= 3 && cvc.length <= 4;
}
}
_validators['card'] = function (num, ctrl, scope, attr) {
var card, ref, typeModel;
if (attr.paymentsTypeModel) {
typeModel = $parse(attr.paymentsTypeModel);
}
var clearCard = function () {
if (typeModel) {
typeModel.assign(scope, null);
}
ctrl.$card = null;
};
// valid if empty - let ng-required handle empty
if (num == null || num.length == 0) {
clearCard();
return true;
}
num = (num + '').replace(/\s+|-/g, '');
if (!/^\d+$/.test(num)) {
clearCard();
return false;
}
card = Cards.fromNumber(num);
if (!card) {
clearCard();
return false;
}
ctrl.$card = angular.copy(card);
if (typeModel) {
typeModel.assign(scope, card.type);
}
ret = (ref = num.length, __indexOf.call(card.length, ref) >= 0) && (card.luhn === false || _luhnCheck(num));
return ret;
}
return function (type, val, ctrl, scope, attr) {
if (!_validators[type]) {
types = Object.keys(_validators);
errstr = 'Unknown type for validation: "' + type + '". ';
errstr += 'Should be one of: "' + types.join('", "') + '"';
throw errstr;
}
return _validators[type](val, ctrl, scope, attr);
}
}])
.factory('_ValidateWatch', ['_Validate', function (_Validate) {
var _validatorWatches = {}
_validatorWatches['cvc'] = function (type, ctrl, scope, attr) {
if (attr.paymentsTypeModel) {
scope.$watch(attr.paymentsTypeModel, function (newVal, oldVal) {
if (newVal != oldVal) {
var valid = _Validate(type, ctrl.$modelValue, ctrl, scope, attr);
ctrl.$setValidity(type, valid);
}
});
}
}
return function (type, ctrl, scope, attr) {
if (_validatorWatches[type]) {
return _validatorWatches[type](type, ctrl, scope, attr);
}
}
}])
.directive('paymentsValidate', ['$window', '_Validate', '_ValidateWatch', function ($window, _Validate, _ValidateWatch) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, elem, attr, ctrl) {
var type = attr.paymentsValidate;
_ValidateWatch(type, ctrl, scope, attr);
var validateFn = function (val) {
var valid = _Validate(type, val, ctrl, scope, attr);
ctrl.$setValidity(type, valid);
return valid ? val : undefined;
};
ctrl.$formatters.push(validateFn);
ctrl.$parsers.push(validateFn);
}
}
}]);
ngSharedDirectives.directive('stPeopleSelector', function (shApi) {
return {
restrict: 'E',
scope: {
'people': '=',
'maxpeople': '=',
'adults': '=',
'childrenundertwelve': '=',
'childrenunderfive': '=',
'showoptions': '=',
'inputname': '@',
'inputmsg': '@',
'personmsg': '@',
'peoplemsg': '@',
'adultmsg': '@',
'adultsmsg': '@',
'childmsg': '@',
'childrenmsg': '@',
'babymsg': '@',
'babiesmsg': '@',
'infantmsg': "@",
'infantsmsg': "@",
'underfivemsg': '@',
'undertwelvemsg': '@',
'closemsg': '@',
'callbackOnClose': '=',
'mainClass': '@',
'isOpen': '=',
'allowrestablish': '=',
'originalpeople': '=',
'originaladults': '=',
'originalundertwelve': '=',
'originalunderfive': '=',
'unselectmsg': '@',
'disabled': '=',
'childseatalert': '=',
'childseatmessage': '@',
'filteralone': '=',
'required': '=',
'indicatepeople': '@',
'noadulterror': '@',
'isfirstsearch': '=',
'isclosed': '=',
},
link: function (scope, elem, attrs, ctrls) {
scope.isOpen = false;
if (scope.disabled === undefined) scope.disabled = false;
var close = $(elem[0]).find('.js-save-button');
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-dropdown-container');
var returnbutton = $(elem[0]).find('.js-return');
if (scope.filteralone == undefined || scope.filteralone == false) {
$(document).mouseup(function (e) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
if (!container.hasClass('hidden')) {
e.preventDefault();
close.trigger('click');
}
}
});
$(document).ready(function (e) {
close.click(function (e) {
container.addClass('hidden');
scope.isOpen = false;
shApi.fullWindow(false);
//callback execution to notify the directives that contain this directive
if (scope.callbackOnClose != undefined && scope.checkForChanges())
scope.callbackOnClose();
});
button.click(function (e) {
if (container.hasClass('hidden')) {
if (!scope.disabled) {
container.removeClass('hidden');
scope.$apply(function () {
scope.isOpen = true;
});
shApi.fullWindow(true);
//init default:
scope.initialValues();
}
} else {
//e.preventDefault();
close.trigger('click');
}
});
returnbutton.click(function (e) {
scope.return();
close.trigger('click');
});
})
}
},
controller: function ($scope) {
$scope.initialValues = function () {
$scope.initAdults = $scope.adults;
$scope.initChildrenUnderFive = $scope.originalunderfive;
$scope.initChildrenUnderTwelve = $scope.originalundertwelve;
$scope.initPeople = $scope.people;
}
//Restablish to before open step (reutrn button mobile only)
$scope.return = function () {
$scope.adults = $scope.initAdults;
$scope.childrenunderfive = $scope.initChildrenUnderFive;
$scope.childrenundertwelve = $scope.initChildrenUnderTwelve;
$scope.people = $scope.initPeople;
}
//Restablish to 0 step
$scope.restablish = function () {
if ($scope.allowrestablish) {
$scope.adults = $scope.originaladults;
$scope.childrenunderfive = $scope.originalunderfive;
$scope.childrenundertwelve = $scope.originalundertwelve;
$scope.people = $scope.originalpeople;
}
}
$scope.checkForChanges = function () {
var changes = false;
if ($scope.adults !== $scope.initAdults || $scope.childrenunderfive !== $scope.initChildrenUnderFive
|| $scope.childrenundertwelve !== $scope.initChildrenUnderTwelve) changes = true;
return changes;
}
$scope.addPeople = function (adult, undertwelve, underfive) {
if (adult != 0) {
$scope.adults += adult;
$scope.people += adult;
}
if (undertwelve != 0) {
$scope.childrenundertwelve += undertwelve;
$scope.people += undertwelve;
}
if (underfive != 0) {
$scope.childrenunderfive += underfive;
$scope.people += underfive;
}
}
$scope.showHideDropdown = function () {
$scope.isclosed = !$scope.isclosed;
}
},
templateUrl: '/Scripts/app/Modules/stPeopleSelectorTemplate.html'
}
});
ngSharedDirectives.directive('stDoubleSelector', function (Translator, shApi) {
var mandatoryData = false;
return {
restrict: 'E',
scope: {
'className': '@',
'mainClass': '@',
'mainItem': '=',
'mainItemKey': '=',
'mainItemName': '@',
'mainOptionList': '=',
'numItemsKey': '=',
'allowSecond': '=',
'secondItem': '=',
'secondItemKey': '=',
'secondItemName': '@',
'secondOptionList': '=',
'actionTrigger': '=',
'firstItemTitle': '@',
'secondItemTitle': '@',
'defaultMsg': '@',
'icon': '@',
'isOpen': '=',
'dropdownAfterElementId': '@',
'leftIcon': '@',
},
link: function (scope, elem, attrs, ctrls) {
scope.isOpen = false;
if (attrs.mandatoryData !== undefined) mandatoryData = (attrs.mandatoryData === 'true' || attrs.mandatoryData === '');
//load invariant translations
scope.acceptMsg = Translator.getTranslation('apply_text');
scope.closeMsg = Translator.getTranslation('cancel_text');
var close = $(elem[0]).find('.js-cancel-button');
var save = $(elem[0]).find('.js-save-button');
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-dropdown-container');
var returnbutton = $(elem[0]).find('.js-return');
if (scope.dropdownAfterElementId !== undefined) {
container = container.insertAfter($("#" + scope.dropdownAfterElementId));
}
$(document).mouseup(function (e) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
if (!container.hasClass('hidden')) {
e.preventDefault();
close.trigger('click');
}
}
});
$(document).ready(function (e) {
// Safari 3.0+ "[object HTMLElementConstructor]"
var isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || (typeof safari !== 'undefined' && safari.pushNotification));
save.click(function (e) {
container.addClass('hidden');
$("#modalcontent").removeClass("modal-responsive");
if (isSafari == true) {
$(".base-selector__footer-mobile").removeClass("base-selector__footer-mobile--safari");
}
$("html").removeClass("fix-footer");
$("html").removeClass("fix-footer__html");
$("body").removeClass("fix-footer__body");
scope.isOpen = false;
shApi.fullWindow(false);
});
close.click(function (e) {
container.addClass('hidden');
$("#modalcontent").removeClass("modal-responsive");
if (isSafari == true) {
$(".base-selector__footer-mobile").removeClass("base-selector__footer-mobile--safari");
}
$("html").removeClass("fix-footer");
$("html").removeClass("fix-footer__html");
$("body").removeClass("fix-footer__body");
scope.isOpen = false;
shApi.fullWindow(false);
//callback execution
scope.onCancel();
});
button.click(function (e) {
if (container.hasClass('hidden')) {
container.removeClass('hidden');
$("#modalcontent").addClass("modal-responsive");
$("html").addClass("fix-footer");
$("html").addClass("fix-footer__html");
$("body").addClass("fix-footer__body");
if (isSafari == true) {
$(".base-selector__footer-mobile").addClass("base-selector__footer-mobile--safari");
}
scope.$apply(function () {
scope.isOpen = true;
});
shApi.fullWindow(true);
//init default:
scope.initialValues();
} else {
//e.preventDefault();
close.trigger('click');
}
});
returnbutton.click(function (e) {
close.trigger('click');
});
})
},
controller: function ($scope) {
//init when open
$scope.initialValues = function () {
$scope.isOpen = true;
if ($scope.allowSecond) {
if ($scope.secondItem != undefined && $scope.secondItem != null)
$scope.lastSecondSelectedKeyValue = $scope.secondItem[$scope.secondItemKey];
}
//Initialize first list
if ($scope.mainOptionList != undefined && $scope.mainOptionList != null) {
var finded = null;
if ($scope.mainItem != undefined && $scope.mainItem != null) {
finded = $.grep($scope.mainOptionList, function (e) { if (e[$scope.mainItemKey] === $scope.mainItem[$scope.mainItemKey]) return e; });
}
if (finded != null && finded.length > 0) {
$scope.mainItemSelected = finded[0];
$scope.$apply();
}
else if (mandatoryData) {
$scope.mainItemSelected = $scope.mainOptionList[0];
$scope.$apply();
}
}
}
$scope.$watch('mainItemSelected', function (newVal, oldVal) {
if (newVal !== oldVal) {
if ($scope.allowSecond && $scope.actionTrigger != undefined && newVal != undefined
&& newVal != null) {
$scope.actionTrigger = 'loadSecondaryValues:' + newVal[$scope.mainItemKey];
}
}
});
$scope.$watch('secondItemSelected', function (newVal, oldVal) {
if (newVal !== oldVal) {
if (newVal != undefined && newVal != null) {
$scope.lastSecondSelectedKeyValue = newVal[$scope.secondItemKey];
}
else
$scope.lastSecondSelectedKeyValue = null;
}
});
$scope.$watch('secondOptionList', function (newValues, oldValues) {
if (newValues != oldValues) {
if ($scope.allowSecond) {
$scope.secondItemSelected = undefined;
if ($scope.secondOptionList != undefined && $scope.secondOptionList != null) {
var finded = null;
if ($scope.lastSecondSelectedKeyValue != null) {
finded = $.grep($scope.secondOptionList, function (e) { if (e[$scope.secondItemKey] === $scope.lastSecondSelectedKeyValue) return e; });
}
if (finded != null && finded.length > 0)
$scope.secondItemSelected = finded[0];
else if (mandatoryData)
$scope.secondItemSelected = $scope.secondOptionList[0];
}
}
}
}, true);
$scope.checkDisabled = function () {
if (($scope.mainItemSelected == undefined || $scope.mainItemSelected == null)
|| ($scope.allowSecond && ($scope.secondItemSelected == undefined || $scope.secondItemSelected == null)))
return true;
return false;
};
$scope.onCancel = function () {
//if ($scope.actionTrigger != undefined) $scope.actionTrigger = 'apply';
//clear internal values
closeAndClearInternalValues();
};
$scope.onSave = function () {
$scope.mainItem = $scope.mainItemSelected;
if ($scope.allowSecond) $scope.secondItem = $scope.secondItemSelected;
if ($scope.actionTrigger != undefined) $scope.actionTrigger = 'apply';
closeAndClearInternalValues();
};
function closeAndClearInternalValues() {
$scope.mainItemSelected = $scope.secondItemSelected = undefined;
$scope.initialMainValue = $scope.initialSecondValue = undefined;
$scope.lastSecondSelectedKeyValue = null;
$scope.secondOptionList = undefined;
$scope.isOpen = false;
};
},
templateUrl: '/Scripts/app/Modules/stDoubleSelectorTemplate.html'
}
});
ngSharedDirectives.directive('stBaggageSelector', function (Translator, shApi) {
return {
restrict: 'E',
scope: {
'totalpackages': '=',
'mediumsuitcase': '=',
'specialbaggage': '=',
'blocksuitcasegroup': '=',
'blockspecificgroup': '=',
'blockmediumsuitcase': '=',
'blocklargesuitcase': '=',
'alternativeoption': '=',
'intromsg': '@',
'specialbaggagedescription': '=',
'suitcaserulemsg': '@',
'specificrulemsg': '@',
'defaultbaggage': '=',
'uptomsg': '@',
'inputmsg': '@',
'mainClass': '@',
'showLabel': '=',
'showIcon': '=',
'closemsg': '@',
'isOpen': '=',
'infomsg': '@',
'titlemsg': '@',
'mediumBaggage': '@',
'mediumBaggageInfo': '@',
'allowrestablish': '=',
'defaulttotalpackages': '=',
'defaultmediumsuitcase': '=',
'unselectmsg': '@',
},
link: function (scope, elem, attrs, ctrls) {
scope.isOpen = false;
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-dropdown-container');
var close = $(elem[0]).find('.js-save-button');
var returnbutton = $(elem[0]).find('.js-return');
$(document).mouseup(function (e) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
if (!container.hasClass('hidden')) {
e.preventDefault();
close.trigger('click');
}
}
});
$(document).ready(function (e) {
close.click(function () {
container.addClass('hidden');
scope.isOpen = false;
shApi.fullWindow(false);
});
button.click(function () {
if (container.hasClass('hidden')) {
container.removeClass('hidden');
scope.initialValues();
scope.$apply(function () {
scope.isOpen = true;
});
shApi.fullWindow(true);
}
else {
close.trigger('click');
}
});
returnbutton.click(function (e) {
scope.return();
close.trigger('click');
});
})
},
controller: function ($scope) {
$scope.addBaggage = function (mediumsuitcase) {
if (mediumsuitcase != 0) {
$scope.mediumsuitcase += mediumsuitcase;
$scope.totalpackages += mediumsuitcase;
}
//Cambia el por defecto
if ($scope.defaultbaggage != undefined)
$scope.defaultbaggage = false;
}
$scope.getTranslation = function (str) {
return Translator.getTranslation(str);
}
$scope.initialValues = function () {
$scope.inittotalpackages = $scope.totalpackages;
$scope.initmediumsuitcase = $scope.mediumsuitcase;
}
$scope.return = function () {
$scope.totalpackages = $scope.inittotalpackages;
$scope.mediumsuitcase = $scope.initmediumsuitcase;
}
$scope.restablish = function () {
if ($scope.allowrestablish) {
$scope.totalpackages = $scope.defaulttotalpackages;
$scope.mediumsuitcase = $scope.defaultmediumsuitcase;
}
}
},
templateUrl: '/Scripts/app/Modules/stBaggageSelectorTemplate.html'
}
}
);
ngSharedDirectives.directive('stRangeSelector', function (shApi) {
return {
restrict: 'E',
scope: {
'inputmsg': '@',
'callbackOnClose': '=',
'minvalue': '=',
'maxvalue': '=',
'stepnum': '=',
'range': '=',
'submsg': '@',
'closemsg': '@',
'units': '@',
'mainClass': '@',
'isOpen': '=',
'disabled': '=',
},
link: function (scope, elem, attrs, ctrls) {
scope.isOpen = false;
if (scope.disabled === undefined) scope.disabled = false;
var close = $(elem[0]).find('.js-save-button');
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-dropdown-container');
$(document).mouseup(function (e) {
if (!scope.fixed) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
if (!container.hasClass('hidden')) {
e.preventDefault();
close.trigger('click');
}
}
}
});
$(document).ready(function (e) {
close.click(function (e) {
container.addClass('hidden');
scope.isOpen = false;
shApi.fullWindow(false);
//callback execution to notify the directives that contain this directive
if (scope.callbackOnClose != undefined && scope.checkForChanges())
scope.callbackOnClose();
});
button.click(function (e) {
if (container.hasClass('hidden')) {
if (!scope.disabled) {
container.removeClass('hidden');
scope.$apply(function () {
scope.isOpen = true;
});
shApi.fullWindow(true);
scope.initialValues();
}
} else {
//e.preventDefault();
close.trigger('click');
}
})
})
},
controller: function ($scope) {
$scope.initialValues = function () {
$scope.minInitial = $scope.range[0];
$scope.maxInitial = $scope.range[1];
}
$scope.checkForChanges = function () {
var changes = false;
if ($scope.minInitial !== $scope.range[0] || $scope.maxInitial !== $scope.range[1]) changes = true;
return changes;
}
},
templateUrl: '/Scripts/app/Modules/stRangeSelectorTemplate.html'
}
});
ngSharedDirectives.directive('inputFocused', function ($timeout, $document) {
return {
scope: { trigger: '@inputFocused' },
link: function (scope, element) {
scope.$watch('trigger', function (value) {
if (value.substr(0, 4) === "true") {
$timeout(function () {
element[0].focus();
element[0].blur();
});
}
});
}
};
});
ngSharedDirectives.directive('stMultiselectDropdown', function ($filter, shApi) {
return {
restrict: 'E',
scope: {
model: '=',
selectedmsg: '@',
options: '=',
titlemsg: '@',
defaultmsg: '@',
unselectmsg: '@',
closemsg: '@',
name: '@',
topBoolName: '@',
callbackOnClose: '=',
id: '@',
multiselectClass: '@',
controlName: '@',
isOpen: '=',
disabled: '=',
mainClass: '@',
bookserviceprovider: '@',
bookserviceproviderselected: '@',
showtags: '=',
filteralone: '=',
isclosed: '=',
filled: '@',
},
templateUrl: '/Scripts/app/Modules/stMultiselectDropdown.html',
link: function (scope, elem, attrs, ctrls) {
if (scope.fixed === undefined) scope.fixed = false;
if (scope.disabled === undefined) scope.disabled = false;
scope.hasIcon = false;
scope.isOpen = false;
scope.hasTopOptions = false;
if (attrs.iconClass !== undefined) { scope.hasIcon = true; scope.iconClass = attrs.iconClass; }
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-dropdown-container');
var close = $(elem[0]).find('.js-save-button');
var returnbutton = $(elem[0]).find('.js-return');
if (scope.filteralone == undefined || scope.filteralone == false) {
$(document).mouseup(function (e) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
if (!container.hasClass('hidden')) {
e.preventDefault();
close.trigger('click');
}
}
});
$(document).ready(function (e) {
close.click(function (e) {
container.addClass('hidden');
scope.isOpen = false;
shApi.fullWindow(false);
if (scope.callbackOnClose != undefined)
scope.callbackOnClose();
});
button.click(function () {
if (container.hasClass('hidden')) {
if (!scope.disabled) {
container.removeClass('hidden');
scope.initialValues();
scope.$apply(function () {
scope.isOpen = true;
});
shApi.fullWindow(true);
}
} else {
container.addClass('hidden');
close.trigger('click');
}
});
returnbutton.click(function (e) {
scope.return();
close.trigger('click');
});
scope.init();
})
} else {
$(document).ready(function (e) {
scope.init();
})
}
},
controller: function ($scope) {
$scope.init = function () {
if ($scope.model == undefined) $scope.model = [];
else loadInternalValues($scope.model);
}
//open
$scope.initialValues = function () {
$scope.initialList = angular.copy($scope.model);
}
//only mobile
$scope.return = function () {
$scope.model = angular.copy($scope.initialList);
}
//Default use as dictionary
$scope.getName = function (option) {
if (typeof $scope.name == 'undefined' || $scope.name == null)
return option["value"];
else
return option[$scope.name];
}
$scope.getValue = function (option) {
if (typeof $scope.id == 'undefined' || $scope.id == null)
return option["key"];
else
return option[$scope.id];
}
$scope.getIsTopOption = function (option) {
var isTopOption = false;
if (typeof $scope.topBoolName != 'undefined' && $scope.topBoolName != null)
isTopOption = option[$scope.topBoolName];
$scope.hasTopOptions |= isTopOption;
return isTopOption;
}
$scope.getIsFilled = function (option) {
if (typeof $scope.filled == 'undefined' || $scope.filled == null)
return option["filled"];
else
return option[$scope.filled];
}
$scope.resumeName = $scope.defaultmsg;
$scope.selectAll = function () {
$scope.model = [];
angular.forEach($scope.options, function (item, index) {
$scope.model.push(item);
});
};
$scope.deselectAll = function () {
$scope.model = [];
};
$scope.toggleSelectItem = function (option) {
var intIndex = -1;
for (var idx in $scope.model) {
if ($scope.getValue(option) == $scope.getValue($scope.model[idx])) {
intIndex = idx;
break;
}
};
if (intIndex >= 0) {
$scope.model.splice(intIndex, 1);
} else {
$scope.model.push(option);
}
};
$scope.getChecked = function (option) {
var varSelected = '';
for (var idx in $scope.model) {
if ($scope.getValue(option) == $scope.getValue($scope.model[idx])) {
varSelected = true;
break;
}
}
return (varSelected);
};
$scope.$watchCollection('model', function (newValue, oldValue) {
if (newValue != undefined && newValue != null) {
loadInternalValues(newValue);
}
});
function loadInternalValues(newValue) {
if ($scope.filteralone != true) {
if (newValue.length > 0) {
if (newValue.length == $scope.options.length) {
$scope.resumeName = $scope.defaultmsg;
}
else {
if ($scope.selectedmsg != undefined && $scope.selectedmsg != null) {
$scope.resumeName = $filter('replace')($scope.selectedmsg, newValue.length);
}
else {
$scope.resumeName = newValue.length;
}
}
}
else {
$scope.resumeName = $scope.defaultmsg;
}
}
}
$scope.showHideDropdown = function () {
$scope.isclosed = !$scope.isclosed;
}
$scope.callApplyTransferFilters = function () {
if ($scope.$parent.callApply == false) {
$scope.$parent.callApply = true;
} else {
$scope.$parent.callApply = false;
}
}
}
}
});
ngSharedDirectives.directive('stSearcherByText', function ($filter, shApi) {
return {
restrict: 'E',
scope: {
model: '=',
unselectmsg: '@',
closemsg: '@',
defaultmsg: '@',
isOpen: '=',
callbackOnClose: '=',
disabled: '=',
mainClass: '@'
},
templateUrl: '/Scripts/app/Modules/stSearcherByText.html',
link: function (scope, elem, attrs, ctrls) {
scope.isOpen = false;
if (scope.fixed === undefined) scope.fixed = false;
if (scope.disabled === undefined) scope.disabled = false;
scope.hasIcon = false;
if (attrs.iconClass !== undefined) { scope.hasIcon = true; scope.iconClass = attrs.iconClass; }
scope.initValueOpen();
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-dropdown-container');
var close = $(elem[0]).find('.js-save-button');
var returnbutton = $(elem[0]).find('.js-return');
$(document).mouseup(function (e) {
if (!scope.fixed) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
if (!container.hasClass('hidden')) {
e.preventDefault();
close.trigger('click');
}
}
}
});
$(document).ready(function (e) {
close.click(function (e) {
scope.closeClick();
});
button.click(function () {
if (container.hasClass('hidden')) {
if (!scope.disabled) {
scope.initValueOpen();
container.removeClass('hidden');
container.find("input").first().focus();
scope.$apply(function () {
scope.isOpen = true;
});
shApi.fullWindow(true);
}
} else {
container.addClass('hidden');
close.trigger('click');
}
})
returnbutton.click(function (e) {
scope.return();
close.trigger('click');
});
});
scope.closeClick = function () {
container.addClass('hidden');
scope.isOpen = false;
shApi.fullWindow(false);
if (scope.callbackOnClose != undefined && scope.checkForChanges())
scope.callbackOnClose();
};
},
controller: function ($scope) {
$scope.initValueOpen = function () {
$scope.initialValue = $scope.model;
}
$scope.return = function () {
$scope.model = $scope.initialValue;
}
$scope.checkForChanges = function () {
var changes = false;
if ($scope.initialValue !== $scope.model) changes = true;
return changes;
}
$scope.$watchCollection('model', function (newValue, oldValue) {
$scope.resumeName = $scope.defaultmsg;
if (newValue != undefined && newValue != null) {
if (newValue.length > 0) {
$scope.resumeName = newValue;
}
}
});
$scope.deselectAll = function () {
$scope.model = null;
};
}
}
});
ngSharedDirectives.directive('stMultiselectPickup', function ($timeout, Purchases, shApi) {
return {
restrict: 'AE',
scope: {
displayAttr: '@',
mainClass: '@',
inputClass: '@',
selectedItems: '=',
allItems: '=',
readOnly: '=',
addItem: '&',
culture: '=',
pickupplaceholdermsg: '@',
pickupsearchmsg: '@',
removeItem: '&',
titlemsg: '@',
},
link: function (scope, elem, attrs) {
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-container');
var returnbutton = $(elem[0]).find('.js-return');
$(document).mouseup(function (e) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
if (!container.hasClass('hidden')) {
e.preventDefault();
closeSelector();
}
}
});
$(document).ready(function (e) {
button.click(function () {
if (container.hasClass('hidden')) {
container.removeClass('hidden');
shApi.fullWindow(true);
} else {
closeSelector();
}
});
returnbutton.click(function (e) {
closeSelector();
});
});
scope.updateSelectedItems = function (obj) {
var selectedObj;
for (i = 0; typeof scope.selectedItems !== 'undefined' && i < scope.selectedItems.length; i++) {
if (scope.selectedItems[i][scope.displayAttr].toUpperCase() === obj[scope.displayAttr].toUpperCase()) {
selectedObj = scope.selectedItems[i];
break;
}
}
if (typeof selectedObj === 'undefined') {
scope.addItem({ item: obj });
} else {
scope.removeItem({ item: selectedObj });
}
closeSelector();
}
scope.isItemSelected = function (item) {
if (typeof scope.selectedItems === 'undefined') return false;
var tmpItem;
for (i = 0; i < scope.selectedItems.length; i++) {
tmpItem = scope.selectedItems[i];
if (typeof tmpItem !== 'undefined'
&& typeof tmpItem[scope.displayAttr] !== 'undefined'
&& typeof item[scope.displayAttr] !== 'undefined'
&& tmpItem[scope.displayAttr].toUpperCase() === item[scope.displayAttr].toUpperCase()) {
return true;
}
}
return false;
}
scope.commaDelimitedSelected = function () {
var list = "";
angular.forEach(scope.selectedItems, function (item, index) {
list += item[scope.displayAttr];
if (index < scope.selectedItems.length - 1) list += ', ';
});
return list.length ? list : scope.pickupplaceholdermsg;
}
function closeSelector() {
container.addClass('hidden');
shApi.fullWindow(false);
}
},
templateUrl: '/Scripts/app/Modules/stMultiselectPickup.html'
}
});
ngSharedDirectives.directive('customTagsinput', function ($timeout, shApi) {
var tagsAfter = false;//by default tags appear before the input element (as in the checked examples)
var maxTags = 0;
//$timeout(function () { console.log('dd'); }, 2000);
return {
restrict: 'EA',
scope: {
inputTagText: '@', inputTagId: '@', inputTagDescription: '@', tagsInputArray: '=', placeHolderContent: '@', typeaheadTooltip: '@', typeaheadCall: "=", typeaheadLabel: '@', maxTags: "=", changesTrigger: '=',
searchTemplate: '@', selectCallback: '=', filters: '='
},
link: function (scope, element, attrs) {
scope.searchDone = false;
$('.tagscontainer').click(function () {
$(this).find('input[type="text"]').focus();
});
//set configuation attrs
//bool tagsAfter to set the position of input elements with regards to tags collection
if (attrs.tagsAfter !== undefined) tagsAfter = (attrs.tagsAfter === 'true' || attrs.tagsAfter === '');
scope.iconClass = attrs.iconClass !== undefined ? attrs.iconClass : 'st-search fa-fw font-up-1';
scope.inputId = attrs.inputId !== undefined ? attrs.inputId : 'tags';
if (scope.filters === undefined) scope.filters = false;
//draws the new tag element where corresponds to configuration above
scope.drawInputTag = function (object) {
//we save the id of the object in the name to have an identification of the object in order to remove it, we do it this way to not rely on text just in case in the future
//we have two texts that are the same but we also have a different description(could be a tooltip)
var htmlSpan = '
' + object[scope.inputTagText]
+ ' ';
if (tagsAfter) $(element).find(".div-search-input").append(htmlSpan);
else $(element).find(".content-tags").append(htmlSpan);
//attaching handler when on click event is fired in a
$(element).find("a[name='" + object[scope.inputTagId] + "']").click(function (event) {
var controlToFocus = $($(this).closest('.text-addon')).find('.controlToFocus')[0];
var id = $(this)[0].name;
scope.removeItem(id);
$(this).parent().parent().remove();//remove text tag
if (scope.filters) {
$('#search-text-tag').val("");
}
var aElement = $(this);
$timeout(function () {
if (controlToFocus) {
$(controlToFocus).focus();
}
});
});
}
scope.clearUnavailableTags = function (newVal, oldVal) {
if (newVal == undefined || newVal === null || newVal.length == 0) {
$(element).find(".tag").remove();
}
else if (newVal != undefined && newVal != null && newVal.length > 0) {
var tagKeys = [];
$.each(newVal, function (idx, item) {
tagKeys.push(item[scope.inputTagId]);
});
var existingTags = $(element).find(".content-tags .tag .removeDiv a");
$.each(existingTags, function (idx, item) {
if (!shApi.checkIfContains(tagKeys, item.name)) {
$(element).find("a[name='" + item.name + "']").parent().parent().remove();
}
});
}
}
scope.readOnly = function (val) {
if (val) {
$(element).find("input").attr("disabled", true);
scope.searchDone = true;
}
else {
$(element).find("input").removeAttr("disabled");
scope.searchDone = false;
}
$(element).find("input").attr("placeholder", attrs.placeHolderContent);
}
scope.addTagFromModel = function (object) {
//Clear input
$(element).find("input").val('');
//Si no existe ya un elemento en la lista
var elem = $(element).find("a[name='" + object[scope.inputTagId] + "']");
if (elem.length === 0) scope.drawInputTag(object);
}
scope.init();
},
controller: function ($scope) {
$scope.selectedObject = "";
//vbles initializations
$scope.init = function () {
if ($scope.tagsInputArray === undefined) $scope.tagsInputArray = [];
else loadInternalValues($scope.tagsInputArray);
//end initializations
}
//typeahead method
$scope.getArrayData = function (filter) {
return $scope.typeaheadCall($scope.selectedObject);
}
//add new item
$scope.newSelectedItem = function () {
//check if the object exists
var obj = $.grep($scope.tagsInputArray, function (e) { return e[$scope.inputTagId] == $scope.selectedObject[$scope.inputTagId]; });
if (obj.length == 0) {
$scope.tagsInputArray.push($scope.selectedObject);
$scope.drawInputTag($scope.selectedObject);
}
$scope.checkMaxTags();
//clean input
$scope.resetSelectedObject();
if ($scope.selectCallback != undefined)
$scope.selectCallback();
}
$scope.removeItem = function (id) {
var index = -1;
$.each($scope.tagsInputArray, function (idx, item) { if (item[$scope.inputTagId] == id) { index = idx; return false; } });
if (index > -1) $scope.tagsInputArray.splice(index, 1);
$scope.checkMaxTags();
}
$scope.checkMaxTags = function () {
if ($scope.tagsInputArray != undefined && $scope.tagsInputArray != null) {
if ($scope.tagsInputArray.length >= $scope.maxTags) {
$scope.readOnly(true);
}
else {
$scope.readOnly(false);
}
}
}
//clean input after adding
$scope.resetSelectedObject = function () {
$scope.selectedObject = "";
//var obj = document.getElementById(activitieSearcher);
//obj.removeClass('open-mobile');
$('.div-input-v2').removeClass('open-mobile');
}
//if language filters is reset from outside controller or service... directive has to reset the DOM
$scope.$watch('tagsInputArray', function (newVal, oldVal) {
$scope.changesTrigger = "tagsChange";
loadInternalValues(newVal);
}, true);
function loadInternalValues(newVal, oldVal) {
$scope.checkMaxTags();
//clean dom tags..
$scope.clearUnavailableTags(newVal, oldVal);
//If the value is reset outside controller
if (newVal != undefined && newVal != null && newVal.length > 0) {
$.each(newVal, function (idx, elem) {
$scope.addTagFromModel(newVal[idx]);
});
}
}
},
templateUrl: "/Scripts/app/Modules/tagsInputTemplate.html"
};
});
ngSharedDirectives.filter('startFrom', function () {
return function (input, start) {
start = +start; //parse to int
return input.slice(start);
}
});
ngSharedDirectives.directive('popoverElem', function () {
return {
link: function (scope, element, attrs) {
element.on('click', function () {
element.addClass('trigger');
});
}
}
});
ngSharedDirectives.directive('popoverClose', function ($timeout) {
return {
scope: {
excludeClass: '@'
},
link: function (scope, element, attrs) {
var trigger = document.getElementsByClassName('trigger');
function closeTrigger(i) {
$timeout(function () {
angular.element(trigger[0]).click();
});
}
element.on('click', function (event) {
var etarget = angular.element(event.target);
var tlength = trigger.length;
if (!etarget.hasClass('trigger') && !etarget.hasClass(scope.excludeClass)) {
for (var i = 0; i < tlength; i++) {
closeTrigger(i);
}
}
});
}
};
});
//Directiva para que funcionen los popovers en un ngRepeat
ngSharedDirectives.directive('bsPopover', function () {
return function (scope, element, attrs) {
element.find("a[rel=popover]").popover({ placement: 'right', html: 'true' });
$('body').on('click', function (e) {
$('a[rel="popover"]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('hide');
}
});
});
};
});
ngSharedDirectives.directive('focusOnElementChange', function ($timeout) {
return {
scope: {
containerToWatch: '=',
elementToFocus: '@',
},
link: function (scope, element, attrs) {
// Focus en el primer control con la clase .controlToFocus en el elemento
scope.$watch('containerToWatch', function (newValue, oldValue) {
if (newValue != oldValue) {
$timeout(function () {
var tab = $($('.' + newValue)[0]);
if (tab) {
var first = tab.find(scope.elementToFocus)[0];
if (first) {
first.focus();
}
}
});
}
});
}
}
});
/*2 decimal places*/
ngSharedDirectives.directive('decimalPlaces', function () {
return {
link: function (scope, ele, attrs) {
ele.bind('keyup keypress', function (e) {
var newVal = $(this).val() + (e.charCode !== 0 ? String.fromCharCode(e.charCode) : '');
if ($(this).val().search(/(.*)\.[0-9][0-9]/) === 0 && newVal.length > $(this).val().length) {
e.preventDefault();
}
});
}
};
});
ngSharedDirectives.directive('focusClass', function () {
return {
restrict: 'A',
priority: 1,
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
var parentClass = null;
if (attrs.focusClassname !== undefined)
parentClass = attrs.focusClassname;
else
parentClass = "div-input-v2"; //default parent class
var parents = element.parents('.' + parentClass);
var parent = parents.first();
if (parent != undefined && parent != null) {
element.bind('focus', function () {
parent.addClass('focus');
}).bind('blur', function () {
parent.removeClass('focus');
});
}
}
};
});
ngSharedDirectives.directive('stAutocomplete', function ($timeout, shApi) {
return {
restrict: 'E',
require: ['^form'],
scope: {
'extraClasses': '@',
'iconClass': '@',
'tamt': '@',
'typeaheadTemplate': '@',
'headerTitle': '@',
'inputId': '@',
'inputName': '@',
'textProperty': '@',
'autocomplete': '=',
'noResultsControl': '=',
'disabled': '=',
'arrayTranslations': '=',
'placeholder': '@',
'fromlistErrorMsg': '@',
'requiredErrorMsg': '@',
'pointErrorMsg': '@',
'tooltipError': '@',
'functionData': '=',
'required': '=',
'classInput': '@',
'clearTags': '=',
'hideOldx': '=',
'showNewx': '=',
'onlyRigth': '=',
'otherInput': '=',
'clearsearchtext': '@',
},
link: function (scope, elem, attrs, ctrls) {
shApi.defineRequired(scope, scope);
scope.form = ctrls[0];
scope.placeholderText = "";
scope.tooltipErrorMode = scope.tooltipError === 'true';
if (scope.disabled === undefined) scope.disabled = false;
if (scope.extraClasses === undefined) scope.extraClasses = "";
if (scope.classInput === undefined) scope.classInput = "";
if (scope.iconClass === undefined) scope.iconClass = "";
if (scope.headerTitle === undefined) scope.headerTitle = "";
if (scope.inputId === undefined) scope.inputId = "";
if (scope.inputName === undefined) scope.inputName = "";
if (scope.textProperty === undefined) scope.textProperty = "";
if (scope.fromlistErrorMsg === undefined) scope.fromlistErrorMsg = "";
if (scope.requiredErrorMsg === undefined) scope.requiredErrorMsg = "";
if (scope.pointErrorMsg === undefined) scope.pointErrorMsg = "";
if (scope.placeholder !== undefined) {
if (scope.arrayTranslations !== undefined)
var text = scope.arrayTranslations[scope.placeholder];
if (text !== undefined)
scope.placeholderText = text;
else
scope.placeholderText = scope.placeholder;
}
},
controller: function ($scope) {
$scope.getTypeaheadData = function (filter) {
return $scope.functionData(filter);
};
$scope.focusElement = function (id) {
$timeout(function () {
document.getElementById(id).focus();
}, 500);
};
$scope.clearInput = function () {
$scope.autocomplete = '';
if ($scope.clearTags == true) {
$scope.otherInput = '';
$scope.$parent.backToSearch();
}
}
},
templateUrl: '/Scripts/app/Modules/stAutocompleteTemplate.html'
};
});
ngSharedDirectives.directive('overlayElement', function () {
return {
restrict: 'A',
scope: {
'overlayElementControl': '=',
'overlayElementExtraId': '@',
'callbackOnClose': '&'
},
link: function (scope, element, attrs, ctrl) {
var extraElement = null;
var overlayElementClass = "overlay-element";
var overlayOpened = false;
var divBackDrop = $('
').addClass("overlay-backdrop");
function setOverlay() {
overlayOpened = true
$(divBackDrop).hide().appendTo('body').fadeIn(50);
$(element).addClass(overlayElementClass);
if (extraElement !== null)
$(extraElement).addClass(overlayElementClass);
}
function removeOverlay() {
overlayOpened = false
divBackDrop.fadeOut(50, function () {
divBackDrop.remove();
$(element).removeClass(overlayElementClass);
if (extraElement !== null)
$(extraElement).removeClass(overlayElementClass);
});
if (scope.callbackOnClose !== undefined) {
scope.$applyAsync(function () {
scope.callbackOnClose();
});
}
}
if (scope.overlayElementControl)
setOverlay();
$(document).ready(function (e) {
if (scope.overlayElementExtraId !== undefined)
extraElement = $("#" + scope.overlayElementExtraId);
scope.$watch('overlayElementControl', function (newValue, oldValue) {
if (newValue != oldValue) {
if (newValue && !overlayOpened) setOverlay();
else if (!newValue && overlayOpened) removeOverlay();
}
});
});
$(document).mouseup(function (e) {
if (overlayOpened && !element.is(e.target) && element.has(e.target).length === 0) {
e.preventDefault();
removeOverlay();
}
});
}
};
});
}
)();
var ngSharedPurchase = angular.module("ngSharedPurchase", []);
(function () {
ngSharedPurchase.factory('shPurchase', ['$timeout', '$rootScope', '$window', '$location', 'CanonicalUrl', 'Translator', '$cookies', 'shApi', '$http', '$state', 'Purchases',
function ($timeout, $rootScope, $window, $location, CanonicalUrl, Translator, $cookies, shApi, $http, $state, Purchases) {
function loadTimesForLanguage(model, lngCode) {
var language = $.grep(model.availableLanguages, function (e) { if (e.languageCode === lngCode) return e; });
var currentTimeList = [];
if (model.materializedData.AskTime) {
$.each(model.availableTimes, function (idx, val) {
if (shApi.containsAnyElement(language[0].productIds, val.productIds)) {
currentTimeList.push(val);
}
});
}
return currentTimeList;
};
function initBaggageOptions(model, g) {
//Initialize baggage opts
model.edition.numMaxSeats = g.InfoBag.NumServices * g.InfoBag.NumPeople;
model.edition.numBaggageItems = g.InfoBag.NumBaggageItems;
model.edition.allowSpecialBaggage = g.InfoBag.AllowSpecialBaggage;
model.edition.blockSuitcaseGroup = false;
model.edition.blockMediumSuitcase = false;
model.edition.blockLargeSuitcase = false;
model.edition.blockSpecificGroup = false;
model.edition.totalBaggage = 0;
model.edition.mediumSuitcase = 0;
model.edition.largeSuitcase = 0;
model.edition.skis = 0;
model.edition.bicycle = 0;
model.edition.golfSticks = 0;
model.edition.hasSpecialBaggage = false;
model.edition.specialBaggageDescription = null;
if (g.DetailedBaggage != null && g.DetailedBaggage.Baggage != null) {
model.edition.mediumSuitcase = g.DetailedBaggage.Baggage.MediumSuitcase;
model.edition.largeSuitcase = g.DetailedBaggage.Baggage.LargeSuitcase;
model.edition.skis = g.DetailedBaggage.Baggage.Skis;
model.edition.bicycle = g.DetailedBaggage.Baggage.Bicycle;
model.edition.golfSticks = g.DetailedBaggage.Baggage.GolfSticks;
if (g.DetailedBaggage.Baggage.SpecialBaggage != null) {
model.edition.hasSpecialBaggage = g.DetailedBaggage.Baggage.SpecialBaggage.HasSpecialBaggage;
model.edition.specialBaggageDescription = g.DetailedBaggage.Baggage.SpecialBaggage.Description;
}
model.edition.totalBaggage = model.edition.mediumSuitcase + model.edition.largeSuitcase + model.edition.skis + model.edition.bicycle + model.edition.golfSticks;
}
};
function areDatesEqual(date1, date2) {
return date1.setHours(0, 0, 0, 0) === date2.setHours(0, 0, 0, 0)
};
function getSeasons(apartmentData, dateFrom, dateTo, numPeople, model) {
var seasons = {};
var currentApartment = apartmentData;
seasons.Error = true;
seasons.Filtered = [];
if (currentApartment.detail.Seasons != null && currentApartment.detail.Seasons.length > 0) {
//var minAvailabilityDate = shApi.getUTCDateFromString(currentApartment.detail.Seasons[0].AvailabilityPeriod.Min);
//var maxAvailabilityDate = shApi.getUTCDateFromString(currentApartment.detail.Seasons[0].AvailabilityPeriod.Max);
$.each(currentApartment.detail.Seasons, function (seasonKey, seasonValue) {
var validSeason = false;
var periodsList = [];
if (seasonValue.AvailabilityPeriod != null) {
//var minDate = minAvailabilityDate.getTime();
//var toDate = dateTo.getTime();
//var diff1 = minDate - toDate;
//var maxDate = maxAvailabilityDate.getTime();
//var fromDate = dateFrom.getTime();
//var diff2 = maxDate - fromDate;
//var fDays = Math.abs(Math.round(diff1 / (1000 * 60 * 60 * 24)));
//var mDays = Math.abs(Math.round(diff2 / (1000 * 60 * 60 * 24)));
var dateMin = shApi.getUTCDateFromString(seasonValue.AvailabilityPeriod.Min);
var dateMax = shApi.getUTCDateFromString(seasonValue.AvailabilityPeriod.Max);
if ((dateFrom <= dateMin && dateTo >= dateMin) || (dateFrom >= dateMin && dateFrom <= dateMax)) {
$.each(seasonValue.FromPrices, function (periodKey, periodValue) {
$.each(periodValue, function (peoplePriceKey, peoplePriceValue) {
if (peoplePriceValue.People.Min <= numPeople && peoplePriceValue.People.Max >= numPeople) {
var period = {};
period.Key = periodKey;
period.Name = peoplePriceValue.Name;
period.FromPrice = peoplePriceValue.FromPrice;
if (period.FromPrice != null || period.FromPrice != undefined) {
validSeason = true;
}
periodsList.push(period);
return true;
}
})
});
}
//else if ((dateFrom < dateMin) && (dateTo < dateMin)) {
// var dMin = dateMin.getDate();
// var dTo = dateTo.getDate();
// var diffewer = dMin - dTo;
// var fewerDays = Math.abs(Math.round(diffewer / (1000 * 60 * 60 * 24)));
//}
//else if ((dateFrom > dateMax) && (dateTo > dateMax)) {
// var dFrom = dateFrom.getDate();
// var dMax= dateMax.getDate();
// var diffmore = dFrom - dMax;
// var moreDays = Math.abs(Math.round(diffmore / (1000 * 60 * 60 * 24)));
//}
}
if (validSeason) {
//seasons = {};
//seasons.Filtered = [];
var season = {};
season.Key = seasonKey;
season.Periods = periodsList;
seasons.Filtered.push(season);
seasons.Error = false;
model.showNoLodgingAvailability = false;
model.seeNextSeason = false;
//return false;
}
//else {
// model.showNoLodgingAvailability = true;
// if ((fewerDays <= fDays) || (moreDays <= mDays)) {
// fDays = fewerDays;
// mDays = moreDays;
// $.each(seasonValue.FromPrices, function (periodKey, periodValue) {
// $.each(periodValue, function (peoplePriceKey, peoplePriceValue) {
// if (peoplePriceValue.People.Min <= numPeople && peoplePriceValue.People.Max >= numPeople) {
// var period = {};
// period.Key = periodKey;
// period.Name = peoplePriceValue.Name;
// period.FromPrice = peoplePriceValue.FromPrice;
// periodsList.push(period);
// return true;
// }
// })
// });
// seasons = {};
// seasons.Filtered = [];
// var season = {};
// season.Key = seasonKey;
// season.Periods = periodsList;
// seasons.Filtered.push(season);
// }
//}
});
}
return seasons;
};
return {
checkBaggageValidity: function (model, totalServices, baggageItems) {
model.blockSuitcaseGroup = false;
var totalItems = totalServices * baggageItems;
if (model.mediumSuitcase >= totalItems) model.blockSuitcaseGroup = true;
},
initializeMaterializedDataGroundRoute: function (model, g) {
model.edition.numServices = g.InfoBag.NumServices;
$.each(model.materializedData.Details, function (idx, item) { if (item["StageNumber"] == 1) { model.orgStage = item; return false; } });
$.each(model.materializedData.Details, function (idx, item) { if (item["StageNumber"] == 2) { model.destStage = item; return false; } });
initBaggageOptions(model, g);
//model.minServiceDate = shApi.getUTCDateFromTime(g.InfoBag.MinJSServiceDate);
//model.maxServiceDate = shApi.getUTCDateFromTime(g.InfoBag.MaxJSServiceDate);
if (model.orgStage != null) {
model.edition.providerDate = shApi.getUTCDateFromString(model.orgStage.ProviderDateService);
if (model.orgStage.FlightNumberOrigin) {
model.edition.flightNumberOrigin1 = model.orgStage.StageInfo.Origin.FlightNumber;
if (model.orgStage.StageInfo.Origin.FlightDate != undefined && model.orgStage.StageInfo.Origin.FlightDate != null) {
model.edition.flightDateOrigin1 = model.edition.flightHourOrigin1 = shApi.getUTCDateFromString(model.orgStage.StageInfo.Origin.FlightDate);
}
}
if (model.orgStage.FlightNumberDestination) {
model.edition.flightNumberDestination1 = model.orgStage.StageInfo.Destination.FlightNumber;
if (model.orgStage.StageInfo.Destination.FlightDate != undefined && model.orgStage.StageInfo.Destination.FlightDate != null) {
model.edition.flightDateDestination1 = model.edition.flightHourDestination1 = shApi.getUTCDateFromString(model.orgStage.StageInfo.Destination.FlightDate);
}
}
model.edition.date = model.edition.dateService = model.edition.hourService = shApi.getUTCDateFromString(model.orgStage.DateHour);
}
if (model.destStage != null) {
//La fecha de vuelta tiene que ser al menos un día posterior a la de ida (por el momento)
model.minReturnServiceDate = shApi.getCompleteDateHour(model.edition.dateService, model.edition.hourService, 1440);
model.maxReturnServiceDate = model.maxServiceDate;
model.edition.returnProviderDate = shApi.getUTCDateFromString(model.destStage.ProviderDateService);
if (model.destStage.FlightNumberOrigin) {
model.edition.flightNumberOrigin2 = model.destStage.StageInfo.Origin.FlightNumber;
if (model.destStage.StageInfo.Origin.FlightDate != undefined && model.destStage.StageInfo.Origin.FlightDate != null) {
model.edition.flightDateOrigin2 = model.edition.flightHourOrigin2 = shApi.getUTCDateFromString(model.destStage.StageInfo.Origin.FlightDate);
}
}
if (model.destStage.FlightNumberDestination) {
model.edition.flightNumberDestination2 = model.destStage.StageInfo.Destination.FlightNumber;
if (model.destStage.StageInfo.Destination.FlightDate != undefined && model.destStage.StageInfo.Destination.FlightDate != null) {
model.edition.flightDateDestination2 = model.edition.flightHourDestination2 = shApi.getUTCDateFromString(model.destStage.StageInfo.Destination.FlightDate);
}
}
model.edition.returnDate = model.edition.returnDateService = model.edition.returnHourService = shApi.getUTCDateFromString(model.destStage.DateHour);
}
},
initializeMaterializedDataGroundRouteShared: function (model, g) {
$.each(model.materializedData.Details, function (idx, item) { if (item["StageNumber"] == 1) { model.orgStage = item; return false; } });
$.each(model.materializedData.Details, function (idx, item) { if (item["StageNumber"] == 2) { model.destStage = item; return false; } });
if (model.orgStage != null) {
model.edition.providerDate = shApi.getUTCDateFromString(model.orgStage.ProviderDateService);
if (model.orgStage.FlightNumberOrigin) {
model.edition.flightNumberOrigin1 = model.orgStage.StageInfo.Origin.FlightNumber;
if (model.orgStage.StageInfo.Origin.FlightDate != undefined && model.orgStage.StageInfo.Origin.FlightDate != null) {
model.edition.flightDateOrigin1 = model.edition.flightHourOrigin1 = shApi.getUTCDateFromString(model.orgStage.StageInfo.Origin.FlightDate);
}
}
if (model.orgStage.FlightNumberDestination) {
model.edition.flightNumberDestination1 = model.orgStage.StageInfo.Destination.FlightNumber;
if (model.orgStage.StageInfo.Destination.FlightDate != undefined && model.orgStage.StageInfo.Destination.FlightDate != null) {
model.edition.flightDateDestination1 = model.edition.flightHourDestination1 = shApi.getUTCDateFromString(model.orgStage.StageInfo.Destination.FlightDate);
}
}
model.edition.date = model.edition.dateService = model.edition.hourService = shApi.getUTCDateFromString(model.orgStage.DateHour);
}
if (model.destStage != null) {
model.edition.returnProviderDate = shApi.getUTCDateFromString(model.destStage.ProviderDateService);
if (model.destStage.FlightNumberOrigin) {
model.edition.flightNumberOrigin2 = model.destStage.StageInfo.Origin.FlightNumber;
if (model.destStage.StageInfo.Origin.FlightDate != undefined && model.destStage.StageInfo.Origin.FlightDate != null) {
model.edition.flightDateOrigin2 = model.edition.flightHourOrigin2 = shApi.getUTCDateFromString(model.destStage.StageInfo.Origin.FlightDate);
}
}
if (model.destStage.FlightNumberDestination) {
model.edition.flightNumberDestination2 = model.destStage.StageInfo.Destination.FlightNumber;
if (model.destStage.StageInfo.Destination.FlightDate != undefined && model.destStage.StageInfo.Destination.FlightDate != null) {
model.edition.flightDateDestination2 = model.edition.flightHourDestination2 = shApi.getUTCDateFromString(model.destStage.StageInfo.Destination.FlightDate);
}
}
model.edition.returnDate = model.edition.returnDateService = model.edition.returnHourService = shApi.getUTCDateFromString(model.destStage.DateHour);
}
},
initDefaultBaggage: function (model) {
//Important: After call initBaggageOptions
if (model.edition != undefined) {
model.edition.defaultTotalBaggage = model.edition.totalBaggage;
model.edition.defaultMediumSuitcase = model.edition.mediumSuitcase;
model.edition.defaultLargeSuitcase = model.edition.largeSuitcase;
model.edition.defaultSkis = model.edition.skis;
model.edition.defaultBicycle = model.edition.bicycle;
model.edition.defaultGolfSticks = model.edition.golfSticks;
model.edition.defaultHasSpecialBaggage = model.edition.hasSpecialBaggage;
model.edition.defaultSpecialBaggageDescription = model.edition.specialBaggageDescription;
}
},
initializeMaterializedDataGroundHourly: function (model, g) {
model.edition.numServices = g.InfoBag.NumServices;
},
fillAdditionalMaterializedData: function (editionData, baggageRevision, currency) {
var p = null;
var c = editionData;
if (c != null) {
p = {};
if (c.addNotes) {
p.NotesForProvider = c.notesForProvider;
}
if (c.flightNumberOrigin1 != undefined && c.flightNumberOrigin1 != null) {
p.OriginFlightNumber = c.flightNumberOrigin1;
}
if (c.flightNumberDestination1 != undefined && c.flightNumberDestination1 != null) {
p.DestinationFlightNumber = c.flightNumberDestination1;
}
if (c.flightDateOrigin1 != undefined && c.flightDateOrigin1 != null) {
p.OriginFlightDate = shApi.serverUTCDateFromTime(c.flightDateOrigin1.getTime());
}
if (c.departuredateflightOrigin1 != undefined && c.departuredateflightOrigin1 != null) {
p.OriginDepartureFlightDate = shApi.serverUTCDateFromTime(c.departuredateflightOrigin1.getTime());
}
if (c.arrivaldateflightOrigin1 != undefined && c.arrivaldateflightOrigin1 != null) {
p.OriginArrivalFlightDate = shApi.serverUTCDateFromTime(c.arrivaldateflightOrigin1.getTime());
}
if (c.flightDateDestination1 != undefined && c.flightDateDestination1 != null) {
p.DestinationFlightDate = shApi.serverUTCDateFromTime(c.flightDateDestination1.getTime());
}
if (c.departuredateflightDestination1 != undefined && c.departuredateflightDestination1 != null) {
p.DestinationDepartureFlightDate = shApi.serverUTCDateFromTime(c.departuredateflightDestination1.getTime());
}
if (c.arrivaldateflightDestination1 != undefined && c.arrivaldateflightDestination1 != null) {
p.DestinationArrivalFlightDate = shApi.serverUTCDateFromTime(c.arrivaldateflightDestination1.getTime());
}
if (c.flightNumberOrigin2 != undefined && c.flightNumberOrigin2 != null) {
p.ReturnOriginFlightNumber = c.flightNumberOrigin2;
}
if (c.flightNumberDestination2 != undefined && c.flightNumberDestination2 != null) {
p.ReturnDestinationFlightNumber = c.flightNumberDestination2;
}
if (c.flightDateOrigin2 != undefined && c.flightDateOrigin2 != null) {
p.ReturnOriginFlightDate = shApi.serverUTCDateFromTime(c.flightDateOrigin2.getTime());
}
if (c.departuredateflightOrigin2 != undefined && c.departuredateflightOrigin2 != null) {
p.ReturnOriginDepartureFlightDate = shApi.serverUTCDateFromTime(c.departuredateflightOrigin2.getTime());
}
if (c.arrivaldateflightOrigin2 != undefined && c.arrivaldateflightOrigin2 != null) {
p.ReturnOriginArrivalFlightDate = shApi.serverUTCDateFromTime(c.arrivaldateflightOrigin2.getTime());
}
if (c.flightDateDestination2 != undefined && c.flightDateDestination2 != null) {
p.ReturnDestinationFlightDate = shApi.serverUTCDateFromTime(c.flightDateDestination2.getTime());
}
if (c.departuredateflightDestination2 != undefined && c.departuredateflightDestination2 != null) {
p.ReturnDestinationDepartureFlightDate = shApi.serverUTCDateFromTime(c.departuredateflightDestination2.getTime());
}
if (c.arrivaldateflightDestination2 != undefined && c.arrivaldateflightDestination2 != null) {
p.ReturnDestinationArrivalFlightDate = shApi.serverUTCDateFromTime(c.arrivaldateflightDestination2.getTime());
}
if (c.userDateMandatory != undefined) {
p.UserDateMandatory = c.userDateMandatory;
}
if (c.returnUserDateMandatory != undefined) {
p.ReturnUserDateMandatory = c.returnUserDateMandatory;
}
if (c.meetingPoint != null && typeof c.meetingPoint.PlaceId !== 'undefined') {
p.MeetingPoint = {};
p.MeetingPoint.PlaceId = c.meetingPoint.PlaceId;
p.MeetingPoint.RawAddress = c.meetingPoint.AutoCompleteText;
}
if (baggageRevision) {
p.DetailedBaggage = {};
p.DetailedBaggage.Bicycle = c.bicycle;
p.DetailedBaggage.GolfSticks = c.golfSticks;
p.DetailedBaggage.LargeSuitcase = c.largeSuitcase;
p.DetailedBaggage.MediumSuitcase = c.mediumSuitcase;
p.DetailedBaggage.Skis = c.skis;
p.DetailedBaggage.SpecialBaggage = {};
p.DetailedBaggage.SpecialBaggage.Description = c.specialBaggageDescription;
p.DetailedBaggage.SpecialBaggage.HasSpecialBaggage = c.hasSpecialBaggage;
}
if (c.date != undefined && c.date != null) {
p.Date = shApi.serverUTCDateFromTime(c.date.getTime());
}
if (c.providerDate != undefined && c.providerDate != null) {
p.providerDate = shApi.serverUTCDateFromTime(c.providerDate.getTime());
}
if (c.returnDate != undefined && c.returnDate != null) {
p.ReturnDate = shApi.serverUTCDateFromTime(c.returnDate.getTime());
}
if (c.duration != undefined && c.duration != null && c.duration > 0) {
p.DurationUnits = c.duration;
}
if (c.languageCode != undefined && c.languageCode != null) {
p.LanguageCode = c.languageCode;
}
p.IsFromFlightManualEdition = c.isFromFlightManualEdition;
p.Currency = currency;
}
return p;
},
meetingPointMaterializedValidity: function (model, path, newVal, oldVal, materializedUid, serviceRequestType, partnerUserCode) {
var stage = 1;
var meetingPoint = newVal;
if (meetingPoint != oldVal) {
var form = shApi.createPath(model.materializedEdition, 'meetingPoint');
if (form != undefined) {
var filled = meetingPoint != null && meetingPoint != undefined && meetingPoint != '';
if (filled) {
if (typeof meetingPoint.PlaceId === 'undefined') {
form.$setValidity('fromlist', false);
form.$setValidity('point', true);
model.meetingPointFromListError = true;
}
else {
form.$setValidity('fromlist', true);
model.meetingPointFromListError = false;
model.blockEditButton = true;
//Check meeting point validity
$http.post(CanonicalUrl.getUrl(model.culture, path), {
materializedUid: materializedUid,
stageNumber: 1,
placeId: meetingPoint.PlaceId,
serviceRequestType: serviceRequestType,
partnerUserCode: partnerUserCode
}).success(function (data, status, headers, config) {
if (data != null && typeof data.IsValid != 'undefined') {
if (!data.IsValid) {
form.$setValidity('point', false);
model.meetingPointErrorMsg[stage] = data.ErrorMsg;
model.meetingPointPointError = true;
} else {
form.$setValidity('point', true);
model.meetingPointErrorMsg[stage] = '';
model.meetingPointPointError = false;
}
model.blockEditButton = false;
} else {
shApi.handleError(model, data);
}
}).error(function (data, status, headers, config) {
shApi.handleError(model, data);
});
}
}
else {
form.$setValidity('fromlist', true);
form.$setValidity('point', true);
model.meetingPointFromListError = false;
model.meetingPointPointError = false;
}
}
}
},
flightNumberValidity: function (newVal, stage) {
var filled = newVal != null && newVal != undefined && newVal != '';
var errorRequired = false;
var errorFromList = false;
var errorCoincidence = false;
if (filled) {
if (typeof newVal.FlightCode === 'undefined') {
errorFromList = true;
}
else {
errorFromList = false;
}
if (!errorFromList) {
//El número de vuelo se pide cuando el origen es aeropuerto, por tanto será el destino de donde viene
var orgCode = stage.ChauffeurDetail.StageInfo.Origin.AirportCode;
if (orgCode != null) {
if (orgCode != newVal.IATADestination) {
errorCoincidence = true;
}
else
errorCoincidence = false;
}
}
}
else {
errorRequired = true;
errorFromList = false;
errorCoincidence = false;
}
var errors = {};
errors.errorFromList = errorFromList;
errors.errorCoincidence = errorCoincidence;
errors.errorRequired = errorRequired;
return errors;
},
showGoogleRouteMap: function (orgLat, orgLon, destLat, destLon) {
var directionsDisplay = new google.maps.DirectionsRenderer();
var directionsService = new google.maps.DirectionsService();
var center = new google.maps.LatLng(orgLat, orgLon);
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: center,
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false,
mapTypeControl: false
});
//Por place id: { placeId: "ChIJc1lGdwfP20YR3lGOMZD-GTM" }
var start = new google.maps.LatLng(orgLat, orgLon);
var end = new google.maps.LatLng(destLat, destLon);
var bounds = new google.maps.LatLngBounds();
bounds.extend(start);
bounds.extend(end);
map.fitBounds(bounds);
var request = {
origin: start,
destination: end,
travelMode: google.maps.TravelMode.DRIVING
};
//TODO: Servidor
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
directionsDisplay.setMap(map);
} else {
//alert("Directions Request from " + start.toUrlValue(6) + " to " + end.toUrlValue(6) + " failed: " + status);
}
});
},
showGooglePointMap: function (mapId, lat, lon) {
var uluru = { lat: lat, lng: lon };
var map = new google.maps.Map(
document.getElementById(mapId),
{
zoom: 4,
center: uluru,
zoomControl: true,
mapTypeControl: false,
scaleControl: false,
streetViewControl: false,
rotateControl: false,
fullscreenControl: true
});
var marker = new google.maps.Marker({ position: uluru, map: map });
map.setZoom(15);
map.panTo(marker.position);
},
showFloatingCart: function() {
$(".all-shopping-cart").addClass('all-shopping-cart--open');
$(".sidebar-shopping-cart__overlay").addClass('sidebar-shopping-cart__overlay--show');
$(".sidebar-shopping-cart__overlay").addClass('sidebar-shopping-cart__overlay--open');
$('html').addClass('delete-scroll');
$('body').addClass('delete-scroll');
$('html').css('padding-right', '0px');
$('html').css('overflow-y', 'hidden');
$('.js-added-correctly').addClass('show');
window.setTimeout(function () {
$(".js-added-correctly").fadeOut(200, function () {
$('.js-added-correctly').removeClass('show');
$('.js-added-correctly').removeAttr('style');
}); }, 5000);
},
//Element resize
onElementHeightChange: function (elm, callback) {
var lastHeight = elm.clientHeight, newHeight;
(function run() {
newHeight = elm.clientHeight;
if (lastHeight != newHeight) callback();
lastHeight = newHeight;
elm.onElementHeightChangeTimer = setTimeout(run, 200);
})();
},
validateCheckFlightOneWay: function (model) {
if ((model.materializedEdition.flightNumberOrigin1.$error.pattern == undefined) && (model.materializedEdition.flightNumberOrigin1.$error.required == undefined)) {
if (model.materializedData.Details[0].FlightNumberOrigin && !model.showFlightConfirmationOrigin1) {
model.materializedEdition.flightNumberOrigin1.$setValidity("valEmptyField", false);
}
else {
model.materializedEdition.flightNumberOrigin1.$setValidity("valEmptyField", true);
}
}
if ((model.materializedEdition.flightNumberDestination1.$error.pattern == undefined) && (model.materializedEdition.flightNumberDestination1.$error.required == undefined)) {
if (model.materializedData.Details[0].FlightNumberDestination && !model.showFlightConfirmationDestination1) {
model.materializedEdition.flightNumberDestination1.$setValidity("valEmptyField", false);
}
else {
model.materializedEdition.flightNumberDestination1.$setValidity("valEmptyField", true);
}
}
},
validateCheckFlightReturn: function (model) {
if ((model.materializedEdition.flightNumberOrigin2.$error.pattern == undefined) && (model.materializedEdition.flightNumberOrigin2.$error.required == undefined)) {
if (model.materializedData.Details[1] != undefined && model.materializedData.Details[1].FlightNumberOrigin && !model.showFlightConfirmationOrigin2) {
model.materializedEdition.flightNumberOrigin2.$setValidity("valEmptyField", false);
}
else {
model.materializedEdition.flightNumberOrigin2.$setValidity("valEmptyField", true);
}
}
if ((model.materializedEdition.flightNumberDestination2.$error.pattern == undefined) && (model.materializedEdition.flightNumberDestination2.$error.required == undefined)) {
if (model.materializedData.Details[1] != undefined && model.materializedData.Details[1].FlightNumberDestination && !model.showFlightConfirmationDestination2) {
model.materializedEdition.flightNumberDestination2.$setValidity("valEmptyField", false);
}
else {
model.materializedEdition.flightNumberDestination2.$setValidity("valEmptyField", true);
}
}
},
cleanFlightFormErrors: function (model) {
if (model.materializedEdition != undefined) {
model.materializedEdition.$setPristine();
model.materializedEdition.$setUntouched();
if (model.materializedEdition.flightNumberOrigin1 != undefined) {
model.materializedEdition.flightNumberOrigin1.$setValidity('valErrorCoincidence', true);
model.materializedEdition.flightNumberOrigin1.$setValidity('valDateWrong', true);
model.materializedEdition.flightNumberOrigin1.$setValidity('valEmptyField', true);
}
if (model.materializedEdition.flightNumberDestination1 != undefined) {
model.materializedEdition.flightNumberDestination1.$setValidity('valDateWrong', true);
model.materializedEdition.flightNumberDestination1.$setValidity('valErrorCoincidence', true);
model.materializedEdition.flightNumberDestination1.$setValidity('valEmptyField', true);
}
if (model.materializedEdition.flightNumberOrigin2 != undefined) {
model.materializedEdition.flightNumberOrigin2.$setValidity('valDateWrong', true);
model.materializedEdition.flightNumberOrigin2.$setValidity('valErrorCoincidence', true);
model.materializedEdition.flightNumberOrigin2.$setValidity('valEmptyField', true);
}
if (model.materializedEdition.flightNumberDestination2 != undefined) {
model.materializedEdition.flightNumberDestination2.$setValidity('valDateWrong', true);
model.materializedEdition.flightNumberDestination2.$setValidity('valErrorCoincidence', true);
model.materializedEdition.flightNumberDestination2.$setValidity('valEmptyField', true);
}
}
},
cleanMeetingPointFormErrors: function (model) {
if (model.materializedEdition != undefined) {
model.materializedEdition.$setPristine();
model.materializedEdition.$setUntouched();
if (model.materializedEdition.meetingPoint != undefined) {
model.meetingPointPointError = false;
model.meetingPointFromListError = false;
}
}
},
establishFiltersOrder: function (orderList, newValue, fltrs) {
var value = null;
if (newValue == 'destinationFilters' || newValue == 'quickFilter') {
orderList = []; //se reestablecen los valores de orden
value = "FirstLevelFilter";
}
else {
if (fltrs.verticals == null || fltrs.verticals.length == 0) {
var index = orderList.indexOf('CategoryFilter');
if (index != undefined && index != -1) orderList.splice(index, 1);
}
if (fltrs.language == null || fltrs.language.length == 0) {
var index = orderList.indexOf('LanguageFilter');
if (index != undefined && index != -1) orderList.splice(index, 1);
}
if (newValue == 'freeText' || newValue == 'date' || newValue == 'freeTours' || newValue == 'providerFilters') {
value = "SecondLevelFilter";
}
else if (newValue == 'verticalFilters') {
value = "CategoryFilter";
}
else if (newValue == 'language') {
value = "LanguageFilter";
}
}
if (value != null) {
if (!shApi.checkIfContains(orderList, value)) {
orderList.push(value);
}
}
return orderList;
},
initServiceSliderList: function (model, group) {
var idGroup = model.materializedList[group].GroupingCode;
var elem = {};
elem = {};
elem.list = [];
elem.listkeys = []; //para pantalla
elem.groupingCode = idGroup;
elem.groupingIndex = group;
elem.currentMaterializedUid = model.materializedList[group].MaterializedServices[0].MaterializedUid;
$.each(model.materializedList[group].MaterializedServices, function (idx, item) {
var materialized = {};
materialized.fullDataLoaded = false;
materialized.detail = {};
materialized.detail.Title = item.Title;
materialized.detail.MainPicture = item.ImgUrl;
materialized.detail.ProviderLogoUrl = item.ProviderLogo;
materialized.detail.Subtitle = item.SubTitle;
materialized.detail.CategoryName = item.CategoryName;
materialized.detail.IsFreeTour = item.IsFreeTour;
materialized.detail.Modifiers = item.Modifiers;
materialized.detail.Rating = item.RatingInfo;
materialized.detail.MaterializedServiceType = item.MaterializedServiceType;
elem.listkeys.push(item.MaterializedUid);
elem.list[item.MaterializedUid] = materialized;
});
model.currentSrvList.push(elem);
},
loadActivityFullInfo: function (model, materializedUid, groupingCode, currencyCode, timeOut, alternativeProvider) {
var currentRequestId = shApi.generateGuid();
model.lastActivityRequestUid = currentRequestId;
//1. Bucar índice en el grupo para encontrar el elemento
var found = model.currentSrvList.find(function (item) { return item.groupingCode == groupingCode; });
var idx = 0;
if (found != null) {
idx = model.currentSrvList.indexOf(found);
}
var totalItems = model.currentSrvList.length;
var idListing = [];
if (alternativeProvider != undefined && alternativeProvider) {
idListing = [idx];
}
else { //TODO: Improve
if (idx - 2 >= 0)
idListing.push(idx - 2);
if (idx - 1 >= 0)
idListing.push(idx - 1);
idListing.push(idx);
if (idx + 1 <= (totalItems - 1))
idListing.push(idx + 1);
if (idx + 2 <= (totalItems - 1))
idListing.push(idx + 2);
}
var materializedIds = [];
$.each(idListing, function (id, val) {
var mainMaterialized = null;
if (materializedUid != null && groupingCode == model.currentSrvList[val].groupingCode) {
mainMaterialized = materializedUid;
}
else {
mainMaterialized = model.currentSrvList[val].currentMaterializedUid;
}
model.currentSrvList[val].currentMaterializedUid = mainMaterialized;
if (!model.currentSrvList[val].list[mainMaterialized].fullDataLoaded) {
materializedIds.push(mainMaterialized);
}
});
$timeout(function () {
if (materializedIds.length > 0 && currentRequestId == model.lastActivityRequestUid) {
Purchases.getActivitiesFullInformation(JSON.stringify(materializedIds), currencyCode, model.prefix)
.then(function (response) {
model.lastResponse = response;
$.each(idListing, function (id, val) {
$.each(model.lastResponse, function (id, item) {
if (model.currentSrvList[val].list[model.lastResponse[id].MaterializedUid] != undefined) {
model.currentSrvList[val].list[model.lastResponse[id].MaterializedUid].error = model.lastResponse[id].Error;
if (!model.lastResponse[id].Error) {
//Hasta que vengan tipados
var typeOfMat = model.currentSrvList[val].list[model.lastResponse[id].MaterializedUid].detail.MaterializedServiceType;
model.currentSrvList[val].list[model.lastResponse[id].MaterializedUid].detail = angular.copy(model.lastResponse[id].Detail);
model.currentSrvList[val].list[model.lastResponse[id].MaterializedUid].detail.MaterializedServiceType = typeOfMat;
}
model.currentSrvList[val].list[model.lastResponse[id].MaterializedUid].fullDataLoaded = true;
}
});
});
model.sliderShow = true;
});
}
}, timeOut);
},
//Participants (Internal process):
convertFormParticipantsToUpload: function(form) {
var list = [];
angular.forEach(form.participantsdata, function (value, key) {
var iterator = value;
var slotKey = key;
var slotList = {};
slotList.slot_key = slotKey;
slotList.slot_values = [];
angular.forEach(iterator, function (value2, key2) {
var aux = {};
aux.participant_key = value2.key;
aux.formvalues = [];
angular.forEach(value2.fields, function (f, key3) {
var auxValue = {};
auxValue.key = f.key;
auxValue.uservalue = f.uservalue;
auxValue.datatype = f.datatype;
aux.formvalues.push(auxValue);
});
slotList.slot_values.push(aux);
});
list.push(slotList);
});
return list;
},
//NEW: TravelManager
chargeActivityOptions2: function (model) {
model.availableTimes = [];
model.availableLanguages = [];
$.each(model.materializedData.Options, function (key, val) {
if (model.materializedData.AskTime) {
var addTo = true;
if (model.availableTimes.length > 0) {
var findTime = $.grep(model.availableTimes, function (e) { return e.index === val.Time.Index; });
if (findTime.length > 0) {
addTo = false;
}
}
if (addTo) {
var time = {};
time.index = val.Time.Index;
time.availableHour = val.Time.AvailableHour;
time.hourFormatted = val.Time.HourFormatted;
time.numLangs = val.Languages != null ? val.Languages.length : 0;
time.productIds = [];
time.productIds.push(key);
model.availableTimes.push(time);
}
else {
for (var currentTime in model.availableTimes) {
if (model.availableTimes[currentTime].index == val.Time.Index) {
model.availableTimes[currentTime].productIds.push(key);
}
}
}
}
if (model.materializedData.AskLanguage) {
if (val.Languages != null) {
for (var idx in val.Languages) {
var language = val.Languages[idx];
var addTo = true;
if (model.availableLanguages.length > 0) {
var findLanguage = $.grep(model.availableLanguages, function (e) { return e.languageCode === language.LanguageCode; });
if (findLanguage.length > 0) {
addTo = false;
}
}
if (addTo) {
var lang = {};
lang.languageCode = language.LanguageCode;
lang.languageName = language.LanguageName;
lang.numTimes = 0;
lang.productIds = [];
lang.productIds.push(key);
model.availableLanguages.push(lang);
}
else {
for (var currentLanguage in model.availableLanguages) {
if (model.availableLanguages[currentLanguage].languageCode == language.LanguageCode) {
model.availableLanguages[currentLanguage].productIds.push(key);
}
}
}
}
}
}
});
if (model.availableTimes.length > 0) {
model.availableTimes = model.availableTimes.sort(shApi.sortBy('index', false, parseInt));
}
if (model.availableLanguages.length > 0) {
model.availableLanguages = model.availableLanguages.sort(shApi.sortBy('code', false));
if (model.availableTimes.length > 0) {
$.each(model.availableLanguages, function (key, val) {
model.availableLanguages[key].numTimes = loadTimesForLanguage(model, model.availableLanguages[key].languageCode).length;
});
}
}
},
loadLanguagesForSelectedTime: function (model, idx) {
var time = $.grep(model.availableTimes, function (e) { if (e.index === idx) return e; });
var currentLanguageList = [];
$.each(model.availableLanguages, function (idx, val) {
if (shApi.containsAnyElement(time[0].productIds, val.productIds)) {
currentLanguageList.push(val);
}
});
return currentLanguageList;
},
loadTimesForSelectedLanguage: function (model, lngCode) {
return loadTimesForLanguage(model, lngCode);
},
//////////////////////////////////
chargeActivityOptions: function (model) {
model.availableTimes = [];
model.availableLanguages = [];
$.each(model.materializedData.Options, function (key, val) {
if (model.materializedData.AskTime) {
var addTo = true;
if (model.availableTimes.length > 0) {
var findTime = $.grep(model.availableTimes, function (e) { return e.index === val.Time.Index; });
if (findTime.length > 0) {
addTo = false;
}
}
if (addTo) {
var time = {};
time.index = val.Time.Index;
time.availableHour = val.Time.AvailableHour;
time.isNotAvailable = false; /*First initization*/
time.hourFormatted = val.Time.HourFormatted;
time.productIds = [];
time.productIds.push(key);
model.availableTimes.push(time);
}
else {
for (var currentTime in model.availableTimes) {
if (model.availableTimes[currentTime].index == val.Time.Index) {
model.availableTimes[currentTime].productIds.push(key);
}
}
}
}
if (model.materializedData.AskLanguage) {
if (val.Languages != null) {
for (var idx in val.Languages) {
var language = val.Languages[idx];
var addTo = true;
if (model.availableLanguages.length > 0) {
var findLanguage = $.grep(model.availableLanguages, function (e) { return e.languageCode === language.LanguageCode; });
if (findLanguage.length > 0) {
addTo = false;
}
}
if (addTo) {
var lang = {};
lang.languageCode = language.LanguageCode;
lang.languageName = language.LanguageName;
lang.isNotAvailable = false; /*First initialization*/
lang.productIds = [];
lang.productIds.push(key);
model.availableLanguages.push(lang);
}
else {
for (var currentLanguage in model.availableLanguages) {
if (model.availableLanguages[currentLanguage].languageCode == language.LanguageCode) {
model.availableLanguages[currentLanguage].productIds.push(key);
}
}
}
}
}
}
});
if (model.availableTimes.length > 0) model.availableTimes = model.availableTimes.sort(shApi.sortBy('index', false, parseInt));
if (model.availableLanguages.length > 0) model.availableLanguages = model.availableLanguages.sort(shApi.sortBy('code', false));
},
selectTimeForActivity: function (model, idx) {
var time = $.grep(model.availableTimes, function (e) { if (e.index === idx) return e; });
var currentNotAvailable = false;
if (model.materializedData.AskLanguage) {
$.each(model.availableLanguages, function (idx, val) {
var contains = shApi.containsAnyElement(time[0].productIds, val.productIds);
if (contains) {
model.availableLanguages[idx].isNotAvailable = false;
}
else model.availableLanguages[idx].isNotAvailable = true;
if (model.selectedLanguage != undefined && model.selectedLanguage != null && model.selectedLanguage.languageCode == val.languageCode
&& model.availableLanguages[idx].isNotAvailable) {
currentNotAvailable = true;
}
});
if (model.selectedLanguage == undefined || model.selectedLanguage == null || currentNotAvailable) {
$.each(model.availableLanguages, function (idx, val) {
if (!val.isNotAvailable) {
model.selectedLanguage = model.availableLanguages[idx];
return false;
}
});
}
}
},
selectLanguageForActivity: function (model, lngCode) {
var language = $.grep(model.availableLanguages, function (e) { if (e.languageCode === lngCode) return e; });
var currentNotAvailable = false;
if (model.materializedData.AskTime) {
$.each(model.availableTimes, function (idx, val) {
var contains = shApi.containsAnyElement(language[0].productIds, val.productIds);
if (contains) {
model.availableTimes[idx].isNotAvailable = false;
}
else model.availableTimes[idx].isNotAvailable = true;
if (model.selectedTime != undefined && model.selectedTime != null && model.selectedTime.index == val.index
&& model.availableTimes[idx].isNotAvailable) {
currentNotAvailable = true;
}
});
if (model.selectedTime == undefined || model.selectedTime == null || currentNotAvailable) {
$.each(model.availableTimes, function (idx, val) {
if (!val.isNotAvailable) {
model.selectedTime = model.availableTimes[idx];
return false;
}
});
}
}
},
getGroupsFilteredForActivity: function (model) {
model.showProductGroups = false;
var products = {};
model.productGroups = {};
model.currentOptions = [];
if (model.materializedData.AskLanguage && model.materializedData.AskTime && model.selectedTime != null && model.selectedLanguage != null) {
var productList = model.selectedTime.productIds.filter(element => model.selectedLanguage.productIds.indexOf(element) !== -1);
$.each(productList, function (idx, val) {
products[val] = model.materializedData.Options[val];
});
}
else if (model.materializedData.AskTime && model.selectedTime != null) {
$.each(model.selectedTime.productIds, function (idx, val) {
products[val] = model.materializedData.Options[val];
});
}
else if (model.materializedData.AskLanguage && model.selectedLanguage != null) {
$.each(model.selectedLanguage.productIds, function (idx, val) {
products[val] = model.materializedData.Options[val];
})
}
else {
products = model.materializedData.Options;
}
//Make groups
$.each(products, function (idx, val) {
var find = model.productGroups[val.FeatureIndex] != undefined;
if (!find) {
var grp = {};
grp.FeatureName = val.FeatureName;
val.Num = 0;
grp.ReferencePVP = val.PVP;
grp.CurrencyMask = val.CurrencyMask;
grp.Options = [];
grp.Options[idx] = val;
model.productGroups[val.FeatureIndex] = grp;
}
else {
if (model.productGroups[val.FeatureIndex].ReferencePVP === 0)
model.productGroups[val.FeatureIndex].ReferencePVP = val.PVP;
val.Num = 0;
model.productGroups[val.FeatureIndex].Options[idx] = val;
}
});
},
selectActivityGroup: function (model, index) {
model.currentOptions = [];
model.currentGroupTitle = model.productGroups[index].FeatureName;
model.edition.minBookingTickets = 0;
model.edition.maxBookingTickets = 0;
model.edition.isGroup = false;
model.edition.maxBookingGroupTickets = 0;
var count = 0;
for (var key in model.productGroups[index].Options) {
var item = model.productGroups[index].Options[key];
var pricingMatrixOrdered = item.PricingMatrix.length > 1 ? item.PricingMatrix.sort(shApi.sortBy('MinTickets', false, parseInt)) : item.PricingMatrix;
if (count == 0) {
model.edition.minBookingTickets = item.MinBookingTickets;
model.edition.maxBookingTickets = item.MaxBookingTickets;
model.edition.isGroup = item.GroupType == 'Group';
if (model.edition.isGroup) {
model.edition.maxBookingGroupTickets = Math.ceil(item.MaxBookingTickets / item.GroupSize);
}
}
var minList = [];
var maxList = [];
for (let i = 0; i < item.PricingMatrix.length; i++) {
minList.push(item.PricingMatrix[i].MinTickets);
maxList.push(item.PricingMatrix[i].MaxTickets);
}
var minValue = Math.min.apply(null, minList);
var maxValue = Math.max.apply(null, maxList);
var opt = {};
opt.Name = item.Name;
opt.MinValue = minValue;
opt.MaxValue = maxValue;
opt.AvailableAlone = item.AvailableAlone;
opt.Code = key;
opt.PVP = item.PVP;
//TODO: price group
opt.UnitaryPrice = pricingMatrixOrdered[0].PVP;
opt.CurrencyMask = item.CurrencyMask;
opt.Num = 0; // default value
opt.IsSoldOut = item.IsSoldout;
opt.PricingMatrix = item.PricingMatrix;
opt.GroupType = item.GroupType;
opt.IsGroup = item.GroupType == 'Group';
opt.GroupSize = item.GroupSize;
opt.AgeBandInfo = item.AgeBandInfo;
opt.HasPriceVariants = item.PricingMatrix.length > 1;
count++;
model.currentOptions.push(opt);
}
//$(".min-tickets-info").removeClass("min-tickets-info--timeout");
$(".action-list-selector__option-animation").removeClass("action-list-selector__option-animation--anim");
},
getActivityTotals: function (model) {
model.edition.totalPrice = 0;
model.edition.totalTickets = 0;
model.edition.totalGroupTickets = 0;
model.edition.hasAvailableAlone = false;
model.edition.options = [];
for (var idx in model.currentOptions) {
var item = model.currentOptions[idx];
if (idx == 0) model.edition.currencyMask = item.CurrencyMask;
var pricingMatrixOrdered = item.PricingMatrix.length > 1 ? item.PricingMatrix.sort(shApi.sortBy('MinTickets', false, parseInt)) : item.PricingMatrix;
if (item.Num > 0) {
//model.edition.totalTickets += item.Num;
var numTickets = Math.trunc(((item.Num - 1) / item.GroupSize) + 1);
var pm = pricingMatrixOrdered.find(function (pricingM) {
return ((pricingM.MinTickets <= item.Num) && (pricingM.MaxTickets >= item.Num));
});
if (pm != undefined && pm != null) {
model.edition.totalPrice += pm.PVP * numTickets;
}
//TODO: price group
model.currentOptions[idx].UnitaryPrice = pm.PVP;
model.edition.totalTickets += item.Num;
if (model.edition.isGroup) {
model.edition.totalGroupTickets = Math.ceil(model.edition.totalTickets / item.GroupSize);
}
var option = {};
option.Units = item.Num;
option.Code = item.Code;
option.GroupSize = item.GroupSize;
option.LanguageCode = model.selectedLanguage != undefined
&& model.selectedLanguage != null ? model.selectedLanguage.languageCode : null;
model.edition.options.push(option);
if (item.AvailableAlone) model.edition.hasAvailableAlone = true;
}
else {
//TODO: price group
model.currentOptions[idx].UnitaryPrice = pricingMatrixOrdered[0].PVP;
}
};
},
deleteActivityOption: function (model, key) {
$.each(model.currentOptions, function (idx, item) {
if (item.Code == key) {
if (item.Num == item.MinValue) item.Num = 0;
else if (item.Num - 1 >= item.MinValue) item.Num--;
return false;
}
});
},
addActivityOption: function (model, key) {
$.each(model.currentOptions, function (idx, item) {
if (item.Code == key) {
if (item.Num == 0) item.Num = item.MinValue;
else if (item.Num + 1 <= item.MaxValue) item.Num++;
return false;
}
});
},
fillAdditionalMaterializedActivity: function (model) {
var finalDate = null;
if (model.edition.date != undefined && model.edition.date != null) {
if (model.materializedData.AskTime)
finalDate = shApi.getCompleteDateHour(model.edition.date, new Date(model.selectedTime.availableHour), 0);
else
finalDate = model.edition.date;
}
var p = {};
p.Options = model.edition.options;
p.PickupSelected = this.fillAdditionalPickupActivity(model);
//if (model.isFromList == true && model.materializedData.AskPickup == true) {
// p.PickupSelected.DisplayName = model.materializedEdition.pickup.DisplayName;
// p.PickupSelected.PlaceId = model.materializedEdition.pickup.PlaceId;
// p.PickupSelected.FromOptionList = false;
//}
//else if (model.isFromList == false && model.materializedData.AskPickup == true) {
// p.PickupSelected.DisplayName = model.materializedEdition.pickup.name;
// p.PickupSelected.PlaceId = model.materializedEdition.pickup.id;
// p.PickupSelectedFromOptionList = true;
//}
p.Date = finalDate != null ? shApi.serverUTCDateFromTime(finalDate.getTime()) : null;
p.LanguageCode = model.selectedLanguage != undefined && model.selectedLanguage != null ? model.selectedLanguage.languageCode : null;
p.PickupSelected = model.selectedPickup;
p.Currency = model.currencyCode;
return p;
},
fillAdditionalPickupActivity: function (model) {
var p = {};
if (model.showPickupToEnter == true && model.materializedData.AskPickup == true) {
p.DisplayName = model.materializedEdition.pickup.DisplayName;
p.PlaceId = model.materializedEdition.pickup.PlaceId;
p.FromOptionList = false;
}
else if (model.showPickupToEnter == false && model.materializedData.AskPickup == true){
p.DisplayName = model.materializedEdition.pickup.name;
p.PlaceId = model.materializedEdition.pickup.id;
p.FromOptionList = true;
}
return p;
},
toogleModalIframeDivs: function (showIframe) {
if (showIframe == true) {
$("#detailIframeLoading").fadeIn(1500).addClass("hidden");
$("#detailIframeDiv").css("visibility", "visible");
}
else {
$("#detailIframeLoading").removeClass("hidden");
$("#detailIframeDiv").css("visibility", "hidden");
}
},
//Llamar en asíncrono on shown.bs.modal
setIframeSourceAndHeight: function (src, listener, toogleModalIframeDivs ) {
var iframeElement = document.getElementById("activityDetailIframeId");
// src = "https://localhost:44300/test.html";
//iframeElement.setAttribute('src', '_blank');
if (iframeElement.getAttribute('src') != src) {
iframeElement.height = 50;
window.CommunicationBridge.getInstance().attachMessageCalback(function (data) {
//TODO: REMOVE When wordpress sends correct data
//This function only should send broadcast
try {
if (data && data.messageType == window.MessageType.Resize) {
console.log("adjust was fired by auto-adjust");
$rootScope.$broadcast("modalIframeResizeReady", true);
return;
}
var increaseSize = 35;
if (data == 1033) {
increaseSize = 820;
}
var receivedHeight = 0;
if ( data !== parseInt( data)) {
if (data.collapse == true) {
console.log("got collapse from event message ");
increaseSize = 0;
}
receivedHeight = data.height;
}
else {
receivedHeight = data;
}
receivedHeight = parseInt(receivedHeight);
if (receivedHeight != NaN ) {
var iframeElement = document.getElementById("activityDetailIframeId");
var height = receivedHeight + increaseSize;
if (iframeElement) {
iframeElement.height = height;
}
$rootScope.$broadcast("modalIframeResizeReady", true);
}
}
catch(e)
{
console.error(e);
}
});
iframeElement.setAttribute("src", src);
}
else {
toogleModalIframeDivs(true);
}
//OJO: Sólo peticiones en dominio , para otras realizar un post hacia el iframe
//iframeElement.onload = function () {
// asignamos el alto del iframe al alto de su contenido.
// var iframe = this;
// if (iframe) {
// var iframeWin = iframe.contentWindow || iframe.contentDocument.parentWindow;
// if (iframeWin.document.body) {
// iframe.height = iframeWin.document.documentElement.scrollHeight || iframeWin.document.body.scrollHeight;
// var containerElement = document.getElementById('material-edition-modal');
// containerElement.style.height = iframe.height + "px";
// }
// }
//};
},
checkDisabledDates: function (date, mode, availableDates) {
var isDisabled = false;
if (availableDates != undefined && availableDates.length > 0) {
if (mode === 'day') {
var available = false;
for (var i = 0; i < availableDates.length; i++) {
if (areDatesEqual(availableDates[i], date)) {
available = true;
}
}
isDisabled = !available;
}
else isDisabled = false;
}
return isDisabled;
},
//**Apartments**//
initApartmentSliderList: function (model, group) {
var idGroup = model.materializedList[group].GroupingCode;
var elem = {};
elem = {};
elem.list = [];
elem.listkeys = []; //para pantalla
elem.groupingCode = idGroup;
elem.groupingIndex = group;
elem.currentMaterializedUid = model.materializedList[group].MaterializedServices[0].MaterializedUid;
$.each(model.materializedList[group].MaterializedServices, function (idx, item) {
var materialized = {};
materialized.fullDataLoaded = false;
materialized.detail = {};
materialized.detail.Title = item.Title;
materialized.detail.MainPicture = item.ImgUrl;
materialized.detail.MainThumbnail = item.MainThumbnail;
materialized.detail.ProviderLogoUrl = item.ProviderLogo;
materialized.detail.DistanceToDetails = item.DistanceToDetails;
materialized.detail.ApartmentCategory = item.ApartmentCategory;
materialized.detail.Price = {};
materialized.detail.Price.PVP = item.Prices.FinalTotal;
materialized.detail.Price.CurrencyMask = item.Prices.CurrencyMask;
materialized.detail.AddressData = item.AddressData;
elem.listkeys.push(item.MaterializedUid);
elem.list[item.MaterializedUid] = materialized;
});
model.currentApartmentList.push(elem);
},
loadApartmentFullInfo: function (model, materializedUid, groupingCode, timeOut, alternativeProvider) {
var currentRequestId = shApi.generateGuid();
model.lastApartmentRequestUid = currentRequestId;
//1. Bucar índice en el grupo para encontrar el elemento
var found = model.currentApartmentList.find(function (item) { return item.groupingCode == groupingCode; });
var idx = 0;
if (found != null) {
idx = model.currentApartmentList.indexOf(found);
}
var totalItems = model.currentApartmentList.length;
var idListing = [];
if (alternativeProvider != undefined && alternativeProvider) {
idListing = [idx];
}
else { //TODO: Improve
if (idx - 2 >= 0)
idListing.push(idx - 2);
if (idx - 1 >= 0)
idListing.push(idx - 1);
idListing.push(idx);
if (idx + 1 <= (totalItems - 1))
idListing.push(idx + 1);
if (idx + 2 <= (totalItems - 1))
idListing.push(idx + 2);
}
var materializedIds = [];
$.each(idListing, function (id, val) {
var mainMaterialized = null;
if (materializedUid != null && groupingCode == model.currentApartmentList[val].groupingCode) {
mainMaterialized = materializedUid;
}
else {
mainMaterialized = model.currentApartmentList[val].currentMaterializedUid;
}
model.currentApartmentList[val].currentMaterializedUid = mainMaterialized;
if (!model.currentApartmentList[val].list[mainMaterialized].fullDataLoaded) {
materializedIds.push(mainMaterialized);
}
});
var infoLoaded = false;
if (model.currentApartmentList[model.currentIndexApartment].list[model.currentApartmentList[model.currentIndexApartment].currentMaterializedUid].fullDataLoaded) {
model.currentSeasons =
getSeasons(model.currentApartmentList[model.currentIndexApartment].list[model.currentApartmentList[model.currentIndexApartment].currentMaterializedUid],
model.apartmentSlider.fromDate, model.apartmentSlider.toDate, model.apartmentSlider.people.numPeople, model);
infoLoaded = true;
}
$timeout(function () {
if (materializedIds.length > 0 && currentRequestId == model.lastApartmentRequestUid) {
Purchases.getApartmentsFullInformation(JSON.stringify(materializedIds), model.prefix)
.then(function (response) {
model.lastResponse = response;
$.each(idListing, function (id, val) {
$.each(model.lastResponse, function (id, item) {
if (model.currentApartmentList[val].list[model.lastResponse[id].MaterializedUid] != undefined) {
model.currentApartmentList[val].list[model.lastResponse[id].MaterializedUid].error = model.lastResponse[id].Error;
if (!model.lastResponse[id].Error) {
model.currentApartmentList[val].list[model.lastResponse[id].MaterializedUid].detail = angular.copy(model.lastResponse[id].Detail);
}
model.currentApartmentList[val].list[model.lastResponse[id].MaterializedUid].fullDataLoaded = true;
}
});
});
//Filtro las seasons iniciales
if (!infoLoaded) {
model.currentSeasons =
getSeasons(model.currentApartmentList[model.currentIndexApartment].list[model.currentApartmentList[model.currentIndexApartment].currentMaterializedUid],
model.apartmentSlider.fromDate, model.apartmentSlider.toDate, model.apartmentSlider.people.numPeople,model);
}
model.sliderShow = true;
});
}
}, timeOut);
},
fillAdditionalMaterializedApartment: function (model) {
var p = {};
if (model.edition.fromDate != undefined && model.edition.fromDate != null) {
p.FromDate = model.edition.fromDate;
}
if (model.edition.toDate != undefined && model.edition.toDate != null) {
p.ToDate = model.edition.toDate;
}
if (model.edition.apartmentPrice != undefined && model.edition.apartmentPrice != null) {
p.TargetPrice = model.edition.apartmentPrice;
}
p.Notes = model.edition.apartmentMsg;
p.People = model.edition.people.numPeople;
p.DetailedPeople ={};
p.DetailedPeople.Adults = model.edition.people.detailedPeople.adults;
p.DetailedPeople.ChildrenUnderFive = model.edition.people.detailedPeople.childrenUnderFive;
p.DetailedPeople.ChildrenUnderTwelve = model.edition.people.detailedPeople.childrenUnderTwelve;
return p;
},
getSeasonsFiltered: function (model, apartmentData, dateFrom, dateTo, numPeople) {
return getSeasons(apartmentData, dateFrom, dateTo, numPeople, model);
},
checkShowPickup: function (model, isReturn, isLoading) {
if (!isReturn) {
if ((model.materializedData.Details[0].FlightNumberOrigin && !model.showFlightConfirmationOrigin1) ||
(model.materializedData.Details[0].FlightNumberDestination && !model.showFlightConfirmationDestination1)) {
model.showPîckup1 = false;
}
else {
model.showPickup1 = true;
}
model.loadingPickup1 = isLoading;
} //Vuelta
else {
if ((model.materializedData.Details[1].FlightNumberOrigin && !model.showFlightConfirmationOrigin2) ||
(model.materializedData.Details[1].FlightNumberDestination && !model.showFlightConfirmationDestination2)) {
model.showPîckup2 = false;
}
else {
model.showPickup2 = true;
}
model.loadingPickup2 = isLoading;
}
},
loadManualFlightInfo: function (model, current, number, departuredate, arrivaldate, iataDepartureDestination, iataArrivalDestination, iataDepartureOrigin, iataArrivalOrigin, isArrival)
{
if (current == "manualFlightInfoOrigin1" || current == "manualFlightInfoDestination1") {
model.isManualOneWay = true;
model.isManualReturn = false;
}
else if (current == "manualFlightInfoOrigin2" || current == "manualFlightInfoDestination2") {
model.isManualOneWay = false;
model.isManualReturn = true;
}
model.manualFlightInfo = {};
model.manualFlightInfo.current = current;
model.manualFlightInfo.number = number != undefined ? number : null;
model.manualFlightInfo.departuredateflight = model.manualFlightInfo.departuredate = model.manualFlightInfo.departurehour = departuredate;
model.manualFlightInfo.arrivaldateflight = model.manualFlightInfo.arrivaldate = model.manualFlightInfo.arrivalhour = arrivaldate;
model.manualFlightInfo.iataDepartureOrigin = iataDepartureOrigin != undefined ? iataDepartureOrigin : null;
model.manualFlightInfo.iataArrivalOrigin = iataArrivalOrigin;
model.manualFlightInfo.iataDepartureDestination = iataDepartureDestination;
model.manualFlightInfo.iataArrivalDestination = iataArrivalDestination != undefined ? iataArrivalDestination : null;
model.manualFlightInfo.isArrival = isArrival;
},
}
}]);
})();
var ngSharedPurchase = angular.module("ngSharedCheckout", []);
(function () {
ngSharedPurchase.factory('shCheckout', ['$timeout', '$rootScope', '$window', '$location', 'CanonicalUrl', 'Translator', '$cookies', 'shApi', '$http', '$state', 'Purchases',
function ($timeout, $rootScope, $window, $location, CanonicalUrl, Translator, $cookies, shApi, $http, $state, Purchases) {
function addNewTraveller(scope, model, isMainTraveller, phoneCode) {
var travellerId = shApi.generateGuid();
model.travellerInformation[travellerId] = {};
initTraveller(scope, model, travellerId, isMainTraveller, false, true, phoneCode);
};
function initTraveller(scope, model, travellerId, isMainTraveller, isCustomer, isNew, phoneCode) {
if (isMainTraveller) model.mainTravellerId = travellerId;
model.travellerInformation[travellerId].name = null;
model.travellerInformation[travellerId].surname = null;
model.travellerInformation[travellerId].birthDate = null;
model.travellerInformation[travellerId].age = null;
model.travellerInformation[travellerId].mainTraveller = isMainTraveller;
model.travellerInformation[travellerId].isCustomer = isCustomer;
model.travellerInformation[travellerId].showAdditionalForm = false;
model.travellerInformation[travellerId].showActivityForm = false;
model.travellerInformation[travellerId].valid = false;
if (isMainTraveller) {
model.travellerInformation[travellerId].phoneCode = phoneCode != undefined ? phoneCode : null;
model.travellerInformation[travellerId].phoneNumber = '';
model.travellerInformation[travellerId].email = null;
//Init aditional data
if (model.participantQuestions.mainTravellerQuestions != null) {
if (model.participantQuestions.mainTravellerQuestions.fields != null && model.participantQuestions.mainTravellerQuestions.fields.length > 0) {
model.travellerInformation[travellerId].travellerFields = angular.copy(model.participantQuestions.mainTravellerQuestions.fields);
checkAndBindParticipantValues(scope, model, travellerId, isMainTraveller, true);
}
if (model.participantQuestions.mainTravellerQuestions.activityQuestions != null && model.participantQuestions.mainTravellerQuestions.activityQuestions.length > 0) {
model.travellerInformation[travellerId].activityFields = angular.copy(model.participantQuestions.mainTravellerQuestions.activityQuestions);
checkAndBindActivitiesParticipantValues(scope, model, travellerId);
model.travellerInformation[travellerId].showActivityForm = true;
}
}
}
else {
//Init aditional data
if (model.participantQuestions.travellerQuestions != null) {
if (model.participantQuestions.travellerQuestions.fields != null && model.participantQuestions.travellerQuestions.fields.length > 0) {
model.travellerInformation[travellerId].travellerFields = angular.copy(model.participantQuestions.travellerQuestions.fields);
checkAndBindParticipantValues(scope, model, travellerId, isMainTraveller, true);
}
if (model.participantQuestions.travellerQuestions.activityQuestions != null && model.participantQuestions.travellerQuestions.activityQuestions.length > 0) {
model.travellerInformation[travellerId].activityFields = angular.copy(model.participantQuestions.travellerQuestions.activityQuestions);
checkAndBindActivitiesParticipantValues(scope, model, travellerId);
model.travellerInformation[travellerId].showActivityForm = true;
}
}
}
};
function checkAndBindParticipantValues(scope, model, travellerId, isMainTraveller) {
var hidden = true;
$.each(model.travellerInformation[travellerId].travellerFields, function (key, val) {
model.travellerInformation[travellerId].travellerFields[key].hidden = false;
model.travellerInformation[travellerId].travellerFields[key].required = true;
switch (val.metatype) {
case 'name':
model.travellerInformation[travellerId].travellerFields[key].hidden = true;
addNameWatcher(scope, model, travellerId, key);
break;
case 'surname':
model.travellerInformation[travellerId].travellerFields[key].hidden = true;
addSurnameWatcher(scope, model, travellerId, key);
break;
case 'leadtraveller':
model.travellerInformation[travellerId].travellerFields[key].hidden = true;
if (isMainTraveller) model.travellerInformation[travellerId].travellerFields[key].uservalue = true;
else model.travellerInformation[travellerId].travellerFields[key].uservalue = false;
break;
case 'iscustomer':
model.travellerInformation[travellerId].travellerFields[key].hidden = true;
if (isMainTraveller) { //1st initialization
if (model.mainTravellerCheck) {
model.travellerInformation[travellerId].isCustomer = model.travellerInformation[travellerId].travellerFields[key].uservalue = true;
model.customerId = travellerId;
}
else {
model.travellerInformation[travellerId].isCustomer = model.travellerInformation[travellerId].travellerFields[key].uservalue = false;
model.customerId = null;
}
}
break;
case 'email':
if (isMainTraveller) {
model.travellerInformation[travellerId].travellerFields[key].hidden = true;
addEmailWatcher(scope, model, travellerId, key);
}
break;
case 'phonenumber':
if (isMainTraveller) {
model.travellerInformation[travellerId].travellerFields[key].hidden = true;
addPhoneWatcher(scope, model, travellerId, key);
}
break;
case 'dateofbirth':
model.travellerInformation[travellerId].travellerFields[key].hidden = true;
addBirthdateWatcher(scope, model, travellerId, key);
break;
default:
break;
}
if (hidden && !model.travellerInformation[travellerId].travellerFields[key].hidden) {
hidden = false;
}
});
if (!hidden) {
model.travellerInformation[travellerId].showAdditionalForm = true;
}
}
function checkAndBindActivitiesParticipantValues(scope, model, travellerId) {
$.each(model.travellerInformation[travellerId].activityFields, function (key, val) {
$.each(val.fields, function (key2, val2) {
model.travellerInformation[travellerId].activityFields[key].fields[key2].hidden = false;
model.travellerInformation[travellerId].activityFields[key].fields[key2].required = true;
});
});
}
function addBirthdateWatcher(scope, model, travellerId, key) {
scope.$watch('Model.travellerInformation["' + travellerId + '"].birthDate', function (newValue, oldValue) {
if (newValue != oldValue) {
if (newValue != undefined && newValue != null) {
model.travellerInformation[travellerId].age = getAge(newValue);
model.travellerInformation[travellerId].travellerFields[key].uservalue = newValue;
}
else {
model.travellerInformation[travellerId].age = null;
model.travellerInformation[travellerId].travellerFields[key].uservalue = null;
}
}
});
}
function addNameWatcher(scope, model, travellerId, key) {
scope.$watch('Model.travellerInformation["' + travellerId + '"].name', function (newValue, oldValue) {
if (newValue != oldValue) {
if (newValue != undefined && newValue != null) {
model.travellerInformation[travellerId].travellerFields[key].uservalue = newValue;
}
else {
model.travellerInformation[travellerId].travellerFields[key].uservalue = null;
}
}
});
}
function addSurnameWatcher(scope, model, travellerId, key) {
scope.$watch('Model.travellerInformation["' + travellerId + '"].surname', function (newValue, oldValue) {
if (newValue != oldValue) {
if(newValue != undefined && newValue != null) {
model.travellerInformation[travellerId].travellerFields[key].uservalue = newValue;
}
else {
model.travellerInformation[travellerId].travellerFields[key].uservalue = null;
}
}
});
}
function addEmailWatcher(scope, model, travellerId, key) {
scope.$watch('Model.travellerInformation["' + travellerId + '"].email', function (newValue, oldValue) {
if (newValue != oldValue) {
if (newValue != undefined && newValue != null) {
model.travellerInformation[travellerId].travellerFields[key].uservalue = newValue;
}
else {
model.travellerInformation[travellerId].travellerFields[key].uservalue = null;
}
}
});
}
function addPhoneWatcher(scope, model, travellerId, key) {
scope.$watch('Model.travellerInformation["' + travellerId + '"].phoneCode', function (newValue, oldValue) {
if (newValue != oldValue) {
if (newValue != undefined && newValue != null && model.travellerInformation[travellerId].phoneNumber != undefined && model.travellerInformation[travellerId].phoneNumber != null) {
model.travellerInformation[travellerId].travellerFields[key].uservalue = model.travellerInformation[travellerId].phoneCode + '-' + model.travellerInformation[travellerId].phoneNumber;
}
else {
model.travellerInformation[travellerId].travellerFields[key].uservalue = null;
}
}
});
scope.$watch('Model.travellerInformation["' + travellerId + '"].phoneNumber', function (newValue, oldValue) {
if (newValue != oldValue) {
if (newValue != undefined && newValue != null && model.travellerInformation[travellerId].phoneCode != undefined && model.travellerInformation[travellerId].phoneCode != null) {
model.travellerInformation[travellerId].travellerFields[key].uservalue = model.travellerInformation[travellerId].phoneCode + '-' + model.travellerInformation[travellerId].phoneNumber;
}
else {
model.travellerInformation[travellerId].travellerFields[key].uservalue = null;
}
}
});
}
function getAge(dateString) {
var today = new Date();
var birthDate = new Date(dateString);
var age = today.getFullYear() - birthDate.getFullYear();
var m = today.getMonth() - birthDate.getMonth();
if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
age--;
}
return age;
};
function checkIfTravellerFormsAreInvalid(model, travellerId, index) {
var error = false;
var formMain = eval('model.travellerFormMain[' + index + ']');
if (formMain === undefined || !formMain.$valid) {
error = true;
}
if (!error && model.travellerInformation[travellerId].showAdditionalForm) {
var formAdditional = eval('model.travellerFormAdditional[' + index + ']');
if (formAdditional === undefined || !formAdditional.$valid) {
error = true;
}
}
if (!error && model.travellerInformation[travellerId].showActivityForm) {
$.each(model.travellerInformation[travellerId].activityFields, function (idx, val) {
var formActivity = eval('model.travellerFormActivity[' + index + '][' + idx + ']');
if (formActivity === undefined || !formActivity.$valid) {
error = true;
return;
}
});
}
return error;
}
function goToStep(number, model) {
switch (number) {
case 1:
model.showFirstStep = true;
model.showFirstStepResume = false;
model.showSecondStep = false;
model.showSecondStepResume = false;
model.showFinalButton = false;
model.showAlertEditionModal = false;
break;
case 2:
model.showSecondStep = true;
model.showSecondStepResume = false;
model.showFinalButton = false;
break;
}
}
function clearActivityTravellerSlotsAssociated(model, key) {
Object.keys(model.activityList[key].options).forEach(function (key2) {
$.each(model.activityList[key].options[key2].optionList, function (id, val) {
model.activityList[key].options[key2].optionList[id].travellerKey = null;
});
});
}
return {
initTravellers: function (scope, model, travelersNumber, phoneCode) {
model.travellerInformation = {};
for (var i = 0; i < travelersNumber; i++) {
addNewTraveller(scope, model, i == 0, phoneCode);
}
model.numberTravelersSelected = true;
model.showTravellerErrors = false;
},
addNewTraveller: function (scope, model, phoneCode) {
addNewTraveller(scope, model, false, phoneCode);
model.showTravellerData = Object.keys(model.travellerInformation).length - 1; //show last added
},
getAge: function (dateString) {
getAge(dateString);
},
saveTravellerData: function(model, index, travellerId) {
var error = checkIfTravellerFormsAreInvalid(model, travellerId, index);
if (!error) {
model.travellerInformation[travellerId].valid = true;
model.showTravellerData = -1;
model.continue = false;
}
else {
model.travellerInformation[travellerId].valid = false;
model.continue = true;
window.setTimeout(function () { shApi.scrollToError(model.formClientData); }, 350);
}
},
clearTravellerData: function (scope, model, travellerId, phoneCode) {
var isMainTraveller = model.travellerInformation[travellerId].mainTraveller;
initTraveller(scope, model, travellerId, isMainTraveller, false, false, phoneCode);
},
checkIfTravellerFormsAreInvalid: function (model, index, travellerId) {
return checkIfTravellerFormsAreInvalid(model, index, travellerId);
},
initializeActivityList: function (model, activityList) {
model.activityList = {};
$.each(activityList, function (key, val) {
model.activityList[val.groupingCode] = {};
model.activityList[val.groupingCode].title = val.title;
model.activityList[val.groupingCode].imgUrl = val.imgUrl;
model.activityList[val.groupingCode].totalSlots = 0;
model.activityList[val.groupingCode].options = {};
var slotsCount = 0;
$.each(val.options, function (key2, val2) {
model.activityList[val.groupingCode].options[val2.code] = {};
model.activityList[val.groupingCode].options[val2.code].name = val2.name;
model.activityList[val.groupingCode].options[val2.code].units = val2.units;
model.activityList[val.groupingCode].options[val2.code].ageBandInfo = val2.ageBandInfo;
model.activityList[val.groupingCode].options[val2.code].optionList = [];
for (i = 0; i < val2.units; i++) {
var opt = {};
opt.travellerKey = null;
model.activityList[val.groupingCode].options[val2.code].optionList.push(opt);
slotsCount = slotsCount + 1;
}
model.activityList[val.groupingCode].totalSlots = slotsCount;
});
});
},
tryMatchTravellersWithSlotAuto: function (scope, model) {
model.travellersTotalAdded = Object.keys(model.travellerInformation).length;
//1. Clear all values:
Object.keys(model.activityList).forEach(function (key) {
clearActivityTravellerSlotsAssociated(model, key);
});
//2. If travellers different from total calculated
if (model.travellersTotalAdded == model.travellerNumberCalculated) {
Object.keys(model.activityList).forEach(function (key) {
if (model.activityList[key].totalSlots == model.travellersTotalAdded) {
var ageBandRangeOptions = 0; // How many are of age band rg??
var totalOptions = 0;
Object.keys(model.activityList[key].options).forEach(function (key2) {
$.each(model.activityList[key].options[key2].optionList, function (id, val) {
totalOptions++;
var optionData = model.activityList[key].options[key2];
if (optionData.ageBandInfo != null && optionData.ageBandInfo.ageFrom != null && optionData.ageBandInfo.ageTo != null) {
ageBandRangeOptions++;
}
});
});
var travellerOptionsAllowed = [];
var allAgeBandOptions = ageBandRangeOptions == totalOptions;
var allNoAgeBandOptions = ageBandRangeOptions == 0;
if (allAgeBandOptions || (allNoAgeBandOptions && Object.keys(model.activityList[key].options).length == 1)) {
Object.keys(model.activityList[key].options).forEach(function (key2) {
Object.keys(model.travellerInformation).forEach(function (key3) {
if (travellerOptionsAllowed[key3] == undefined || travellerOptionsAllowed[key3] == null) {
travellerOptionsAllowed[key3] = [];
}
if (allAgeBandOptions) {
var optionData = model.activityList[key].options[key2];
var ageTraveller = model.travellerInformation[key3].age;
if (ageTraveller >= optionData.ageBandInfo.ageFrom && ageTraveller <= optionData.ageBandInfo.ageTo) {
travellerOptionsAllowed[key3].push(key2);
}
}
else {
travellerOptionsAllowed[key3].push(key2);
}
});
});
var matched = 0;
Object.keys(travellerOptionsAllowed).forEach(function (key4) {
//Not allowed or allowed in more than one..
if (travellerOptionsAllowed[key4].length == 1) {
var opt = travellerOptionsAllowed[key4][0];
$.each(model.activityList[key].options[opt].optionList, function (id, val) {
if (model.activityList[key].options[opt].optionList[id].travellerKey == null) {
model.activityList[key].options[opt].optionList[id].travellerKey = key4;
matched++;
return false;
}
});
}
});
//Only fullfill if all options can be matched
if (matched != totalOptions) {
clearActivityTravellerSlotsAssociated(model, key);
}
}
}
});
}
},
selectParticipant: function (model, activityKey, slotKey, participantIndex, travellerKey, btnId) {
var participantData = model.activityList[activityKey].options[slotKey].optionList[participantIndex];
if (travellerKey !== participantData.travellerKey) {
model.activityList[activityKey].options[slotKey].optionList[participantIndex].travellerKey = travellerKey;
//Check duplicity and clear
$.each(model.activityList[activityKey].options, function (slotKey2, slotValue2) {
$.each(slotValue2.optionList, function (participantIndex2, participantValue2) {
if (participantValue2.travellerKey == travellerKey && !(slotKey2 == slotKey && participantIndex2 == participantIndex)) {
model.activityList[activityKey].options[slotKey2].optionList[participantIndex2].travellerKey = null;
}
});
});
}
model.participantSelectorOpen[btnId] = false;
},
setParticipantTravellerCustomer: function (model, isCustomer) {
var travellerId = model.mainTravellerId;
$.each(model.travellerInformation[travellerId].travellerFields, function (key, val) {
if (val.metatype == "iscustomer") {
if (isCustomer) {
model.travellerInformation[travellerId].isCustomer = model.travellerInformation[travellerId].travellerFields[key].uservalue = true;
model.customerId = travellerId;
}
else {
model.travellerInformation[travellerId].isCustomer = model.travellerInformation[travellerId].travellerFields[key].uservalue = false;
model.customerId = travellerId;
}
return;
}
});
},
fillBuyerDataWithTravellerData: function (model) {
var mainTraveller = model.travellerInformation[model.mainTravellerId];
model.buyerData = {};
model.buyerData.email = mainTraveller.email;
model.buyerData.name = mainTraveller.name;
model.buyerData.surname = mainTraveller.surname;
model.buyerData.phoneCode = mainTraveller.phoneCode;
model.buyerData.phone = mainTraveller.phoneNumber;
},
copyBuyerDataToParticipantAsClient: function (model) {
var travellerId = model.customerId;
model.travellerInformation[travellerId].name = model.buyerData.name;
model.travellerInformation[travellerId].surname = model.buyerData.surname;
//model.travellerInformation[travellerId].email = model.buyerData.email; //same as participant
model.travellerInformation[travellerId].phoneCode = model.buyerData.phoneCode;
model.travellerInformation[travellerId].phoneNumber = model.buyerData.phone;
},
clearBuyerData: function (model, phoneCode) {
model.buyerData = {};
model.buyerData.email = null;
model.buyerData.name = null;
model.buyerData.surname = null;
model.buyerData.phoneCode = phoneCode != undefined ? phoneCode : null;
model.buyerData.phone = null;
},
saveParticipants: function (model) {
model.showFinalButton = false;
model.showParticipantsErrors = false;
model.showAgeErrors = false;
var totalNoValid = 0;
var valid = true;
$.each(model.activityList, function (activityKey, activityItem) {
$.each(activityItem.options, function (slotKey, slotValue) {
model.ageInfo = {};
model.ageInfo.ageFrom = slotValue.ageBandInfo.ageFrom;
model.ageInfo.ageTo = slotValue.ageBandInfo.ageTo;
$.each(slotValue.optionList, function (optionIndex, optionValue) {
if (optionValue.travellerKey == undefined || optionValue.travellerKey == null || optionValue.travellerKey == '') {
valid = false;
model.showParticipantsErrors = true;
model.showAgeErrors = true;
totalNoValid += 1;
}
$.each(model.travellerInformation, function (travellerKey, travellerInfo) {
if (optionValue.travellerKey == travellerKey) {
if ((model.ageInfo.ageFrom == undefined || model.ageInfo.ageTo == undefined) || (travellerInfo.age >= model.ageInfo.ageFrom && travellerInfo.age <= model.ageInfo.ageTo)) {
valid = true;
} else {
valid = false;
model.showAgeErrors = true;
model.showParticipantsErrors = true;
totalNoValid += 1;
}
}
});
});
});
});
if (totalNoValid == 0) {
valid = true;
model.showFinalButton = true;
model.showSecondStep = false;
model.showSecondStepResume = true;
}
else {
valid = false;
model.continue = true;
}
return valid;
},
goToStep: function (number, model) {
goToStep(number, model);
},
editFirstStep: function (model) {
if (model.participantsNeeded) {
model.showAlertEditionModal = true;
}
else {
goToStep(1, model);
}
},
getTravellersDataFormattedToUpload: function (model) {
var travellersData = [];
$.each(model.travellerInformation, function (key, val) {
var traveller = {};
traveller.code = key;
traveller.data = {};
traveller.data.code = key;
traveller.data.name = val.name;
traveller.data.surname = val.surname;
traveller.data.birthDate = shApi.serverUTCDateFromTime(val.birthDate.getTime());
if (val.phoneCode != undefined && val.phoneCode != null && val.phoneNumber != undefined && val.phoneNumber != null) {
traveller.data.phone = val.phoneCode + '-' + val.phoneNumber;
}
traveller.data.mainTraveller = val.mainTraveller;
traveller.data.isCustomer = val.isCustomer;
traveller.data.email = val.email;
traveller.formValues = null;
traveller.activityParticipantsData = null;
if (val.travellerFields != undefined && val.travellerFields != null) {
traveller.formValues = [];
$.each(val.travellerFields, function (key3, val3) {
var auxValue = {};
auxValue.key = key3;
auxValue.datatype = val3.datatype;
auxValue.metatype = val3.metatype;
if (val3.datatype == 'date')
auxValue.uservalue = shApi.serverUTCDateFromTime(val3.uservalue.getTime());
else
auxValue.uservalue = val3.uservalue;
traveller.formValues.push(auxValue);
});
}
if (val.activityFields != undefined && val.activityFields != null) {
traveller.activityFormValues = [];
$.each(val.activityFields, function (key2, val2) {
var activity = {};
activity.groupingCode = val2.groupingCode;
activity.formValues = [];
$.each(val2.fields, function (key3, val3) {
var auxValue = {};
auxValue.key = key3;
auxValue.uservalue = val3.uservalue;
auxValue.datatype = val3.datatype;
auxValue.metatype = val3.metatype;
activity.formValues.push(auxValue);
});
traveller.activityFormValues.push(activity);
});
}
travellersData.push(traveller);
});
return travellersData;
},
getActivityTravellersMatchedFormattedToUpload: function (model) {
var activityTravellers = [];
$.each(model.activityList, function (key, val) {
var activity = {};
activity.serviceGroup = key;
activity.options = [];
$.each(val.options, function (key2, val2) {
var option = {};
option.code = key2;
option.travellerKeys = [];
for (i = 0; i < val2.optionList.length; i++) {
option.travellerKeys.push(val2.optionList[i].travellerKey);
}
activity.options.push(option);
});
activityTravellers.push(activity);
});
return activityTravellers;
},
}
}]);
})();
var ngDynamicFormRender = angular.module("ngDynamicFormRender", ['ngTranslator', 'ngSharedApi', 'ngResource', 'ui.bootstrap']);
(function (Translator, shApi, $compile) {
ngDynamicFormRender.directive('stDynamicFormRender', function ($parse, $compile, shApi) {
var supportedTypes = ['string', 'boolean', 'integer', 'number', 'liststring', 'date', 'multioptionliststring', 'listinteger', 'multioptionlistinteger'];
var parentForm = null;
var newForm = null;
var responsive = false;
return {
restrict: 'E',
transclude: true,
scope: {
data: '=',
formName: '=',
culture: '=',
continue: '=',
arrayMessages: '=',
},
link: function ($scope, element, attrs) {
if (attrs.responsive !== undefined) responsive = (attrs.responsive === 'true' || attrs.responsive === '');
//Conversions
$scope.internalModelDic = [];
shApi.defineRequired($scope, $scope);
newForm = angular.element('
');
//Build fields
angular.forEach($scope.data, buildFields);
$compile(newForm)($scope)
element.append(newForm);
function buildFields(field, idx) {
if (shApi.checkIfContains(supportedTypes, field.datatype)) {
var modelField = 'data[' + idx + ']';
var newElement = angular.element('
');
if (responsive)
newElement.attr('class', 'field col-xs-12 col-md-6');
else
newElement.attr('class', 'field');
newElement.attr('ng-if', '!' + modelField + '.hidden'); //Only show vald
var fieldName = getFieldName(field);
var fieldContainer = getFieldContainer(field, fieldName, modelField);
var fieldDiv = getFieldDiv(field, fieldName);
var errors = [];
if (field.datatype === 'string') {
var newFieldElem = '';
newElement.append(getLabelElem(field));
if (field.metatype === 'phonenumber') {
$scope.internalModelDic[modelField] = {};
fieldDiv.addClass("content-input--phone");
//init (format 34-654354345)
if ($scope.data[idx].uservalue != undefined && $scope.data[idx].uservalue != null) {
var splitValue = $scope.data[idx].uservalue.split("-");
$scope.internalModelDic[modelField].uservalueaux = splitValue[0]; //phoneNumber
$scope.internalModelDic[modelField].uservalue = splitValue[1]; //phoneCode
}
else {
$scope.internalModelDic[modelField].uservalue = '';
$scope.internalModelDic[modelField].uservalueaux = null;
}
var phoneCodeSpan = angular.element('
+{{internalModelDic[\'' + modelField + '\'].uservalueaux}} ');
fieldDiv.prepend(phoneCodeSpan);
newFieldElem = angular.element('
');
addPhoneWatchers(modelField, fieldName);
} //text label
else if (field.metatype === 'starttime' || field.metatype === 'endtime' || field.metatype === 'inboundflighttime' || field.metatype === 'outboundflighttime') {
fieldContainer.attr("ng-class", "{'focus': " + fieldName + "open }")
$scope.internalModelDic[modelField] = {};
$scope.internalModelDic[modelField].uservalue = null;
newFieldElem = angular.element('
'
);
if (field.required) {
errors.push(getElementRequiredError(field, fieldName));
}
//Convert dates
if (field.range != null) {
$scope.internalModelDic[modelField].range = {};
$scope.internalModelDic[modelField].range.Min = shApi.getUTCDateFromString(getMinRange(field));
$scope.internalModelDic[modelField].range.Max = shApi.getUTCDateFromString(getMaxRange(field));
newFieldElem.attr('min-date', 'internalModelDic["' + modelField + '"].range.Min');
newFieldElem.attr('max-date', 'internalModelDic["' + modelField + '"].range.Max');
errors.push(getElementMinDateError(field, fieldName));
errors.push(getElementMaxDateError(field, fieldName));
}
if (field.uservalue != null) {
$scope.internalModelDic[modelField].uservalue = shApi.getUTCDateFromString(field.uservalue);
}
fieldContainer.append(newFieldElem);
//Add watchers (convert data format)
addDateWatchers(modelField, fieldName);
}
else {
newFieldElem = angular.element('
');
newFieldElem.attr('name', fieldName);
}
addPatternValidationIfNeeded(newFieldElem, errors, field, fieldName);
if (field.range != null) {
newFieldElem.attr('ng-minlength', getMinRange(field));
newFieldElem.attr('ng-maxlength', getMaxRange(field));
errors.push(getElementMinLengthError(field, fieldName));
errors.push(getElementMaxLengthError(field, fieldName));
}
if (field.required) {
errors.push(getElementRequiredError(field, fieldName));
}
fieldContainer.append(fieldDiv);
fieldDiv.append(newFieldElem);
}
else if (field.datatype === 'integer' || field.datatype === 'number') {
newElement.append(getLabelElem(field));
var newFieldElem = angular.element('
');
newFieldElem.attr('name', fieldName);
//Integer no decimals
if (field.datatype === 'integer') {
newFieldElem.attr('step', 1);
newFieldElem.attr('ng-pattern', '^[1-9][0-9]*$');
} //Number -> default 2 decimals
else {
newFieldElem.attr('step', .01);
newFieldElem.attr('ng-pattern', '/^[1-9][0-9]*(\.[0-9]{1,2})?$/')
}
errors.push(getElementPatternError(field, fieldName));
if (field.range != null) {
newFieldElem.attr('min', getMinRange(field));
newFieldElem.attr('max', getMaxRange(field));
errors.push(getElementMinError(field, fieldName));
errors.push(getElementMaxError(field, fieldName));
}
if (field.required) {
errors.push(getElementRequiredError(field, fieldName));
}
fieldContainer.append(fieldDiv);
fieldDiv.append(newFieldElem);
}
else if (field.datatype === 'boolean') {
var idcheckbox = 'checkbox-' + fieldName;
var newFieldElem = angular.element('
' + field.labelname + '');
fieldContainer.append(fieldDiv);
fieldDiv.append(newFieldElem);
}
else if (field.datatype === 'liststring' || field.datatype === 'listinteger') {
newElement.append(getLabelElem(field));
//Only one selectionable option
var defaultMsg = "--" + getMessage("list_default_option") + "--";
var newFieldElem = angular.element('
' +
'' + defaultMsg + ' ' +
'{{ option.text }} ' +
' ');
if (field.required) {
errors.push(getElementRequiredError(field, fieldName));
}
fieldContainer.append(fieldDiv);
fieldDiv.append(newFieldElem);
}
else if (field.datatype === 'date') {
newElement.append(getLabelElem(field));
fieldContainer.attr("ng-class", "{'error': fieldHasError(" + getFormFieldRoute(fieldName) + "), 'focus': " + fieldName + "open }");
$scope.internalModelDic[modelField] = {};
$scope.internalModelDic[modelField].uservalue = null;
var newFieldElem = angular.element('
'
);
if (field.required) {
newFieldElem.attr('required', true);
errors.push(getElementRequiredError(field, fieldName));
}
//Convert dates
if (field.range != null) {
$scope.internalModelDic[modelField].range = {};
$scope.internalModelDic[modelField].range.Min = shApi.getUTCDateFromString(getMinRange(field));
$scope.internalModelDic[modelField].range.Max = shApi.getUTCDateFromString(getMaxRange(field));
newFieldElem.attr('min-date', 'internalModelDic["' + modelField + '"].range.Min');
newFieldElem.attr('max-date', 'internalModelDic["' + modelField + '"].range.Max');
errors.push(getElementMinDateError(field, fieldName));
errors.push(getElementMaxDateError(field, fieldName));
}
if (field.uservalue != null) {
$scope.internalModelDic[modelField].uservalue = shApi.getUTCDateFromString(field.uservalue);
}
fieldContainer.append(newFieldElem);
//Add watchers (convert data format)
addDateWatchers(modelField, fieldName);
}
else if (field.datatype == 'multioptionliststring' || field.datatype == 'multioptionlistinteger') {
newElement.append(getLabelElem(field));
var divCheckbox = angular.element('
');
var contentCheckbox = angular.element('
');
var inputElement = angular.element('
');
var labelElement = angular.element('
{{option.text}} ');
contentCheckbox.append(inputElement);
contentCheckbox.append(labelElement);
divCheckbox.append(contentCheckbox);
fieldContainer.append(fieldDiv);
fieldDiv.append(divCheckbox);
}
if (fieldContainer != null) {
newElement.append(fieldContainer);
if (errors.length > 0) {
newElement.append(errors);
}
newForm.append(newElement);
}
}
};
//Messages and Translations
function getMessage(key) {
return $scope.arrayMessages[key];
};
//Create main element
function getFieldName(field) {
var name = field.key;
return name;
};
function getFieldContainer(field, fieldName) {
var htmlcontainer = '';
if (field.datatype === 'boolean') {
htmlcontainer = '
';
}
else if (field.datatype === 'multioptionliststring' || field.datatype === 'multioptionlistinteger') {
htmlcontainer = '
';
}
else {
htmlcontainer = '
';
}
return angular.element(htmlcontainer);
};
function getFieldDiv(field) {
var htmlcontainer = '';
if (field.datatype === 'boolean') {
htmlcontainer = '
';
}
else if (field.datatype === 'multioptionliststring' || field.datatype === 'multioptionlistinteger') {
htmlcontainer = '
';
}
else {
htmlcontainer = '
';
}
return angular.element(htmlcontainer);
};
function getLabelElem(field) {
return angular.element('
' + field.labelname + ' ');
};
function getFormFieldRoute(fieldName) {
return 'formName.' + fieldName;
}
//Base error elem
function getErrorElem(msg) {
return angular.element('
' + msg + ' ');
}
function addPatternValidationIfNeeded(newFieldElem, errors, field, fieldName) {
var patternError = null;
var customMsg = null;
switch (field.metatype) {
case 'email':
patternError = getMessage('email_pattern');
customMsg = getMessage('email_pattern_errormsg');
break;
case 'phonenumber':
patternError = getMessage('phone_pattern');
customMsg = getMessage('phone_pattern_errormsg');
break;
}
if (patternError != null) {
newFieldElem.attr('ng-pattern', '/' + patternError + '/');
errors.push(getElementPatternError(field, fieldName, customMsg));
}
}
////////////////////////////////////////////////
//Watchers
function addDateWatchers(modelField, fieldName) {
$scope.$watch(modelField + '.uservalue', function (newValue, oldValue) {
if (newValue !== oldValue) {
if (newValue !== undefined && newValue !== null) {
$scope.internalModelDic[modelField].uservalue = shApi.getUTCDateFromString(newValue);
}
else {
$scope.internalModelDic[modelField].uservalue = null;
}
}
});
$scope.$watch('internalModelDic[\'' + modelField + '\'].uservalue', function (newValue, oldValue) {
var newValDate = newValue != undefined ? newValue.getTime() : newValue;
var oldValDate = oldValue != undefined ? oldValue.getTime() : oldValue;
var modelScope = $scope.$eval(modelField);
if (newValDate !== oldValDate && modelScope !== undefined) {
checkDateValidity(newValue, modelField, fieldName);
if (newValDate !== undefined && newValDate !== null) {
modelScope.uservalue = shApi.serverUTCDateFromTime(newValue);
}
else {
modelScope.uservalue = null;
}
}
});
}
function addPhoneWatchers(modelField, fieldName) {
$scope.$watch(modelField + '.uservalue', function (newValue, oldValue) {
if (newValue !== oldValue) {
if (newValue !== undefined && newValue !== null && newValue != '') {
//Split values
var splitValue = newValue.split("-");
$scope.internalModelDic[modelField].uservalueaux = splitValue[0];
$scope.internalModelDic[modelField].uservalue = splitValue[1];
}
else {
$scope.internalModelDic[modelField].uservalue = '';
$scope.internalModelDic[modelField].uservalueaux = undefined;
}
}
});
$scope.$watch('internalModelDic[\'' + modelField + '\'].uservalue', function (newValue, oldValue) {
if (newValue !== oldValue) {
var modelScope = $scope.$eval(modelField);
if (modelScope !== undefined) {
var newVal = newValue == undefined || newValue == null ? '' : newValue;
modelScope.uservalue = $scope.internalModelDic[modelField].uservalueaux + '-' + newVal;
}
}
});
$scope.$watch('internalModelDic[\'' + modelField + '\'].uservalueaux', function (newValue, oldValue) {
if (newValue !== oldValue) {
var modelScope = $scope.$eval(modelField);
if (modelScope !== undefined) {
modelScope.uservalue = newValue + '-' + $scope.internalModelDic[modelField].uservalue;
}
}
});
}
//////////////////////////
//min-max validation
function checkDateValidity(newDate, modelField, fieldName) {
var route = $scope.$eval(getFormFieldRoute(fieldName));
if (route !== undefined && $scope.internalModelDic[modelField].range !== null) {
if (newDate !== undefined && newDate !== null) {
if (newDate > $scope.internalModelDic[modelField].range.Max) {
route.$setValidity('maxdate', false);
}
else {
route.$setValidity('maxdate', true);
}
if (newDate < $scope.internalModelDic[modelField].range.Min) {
route.$setValidity('mindate', false);
}
else {
route.$setValidity('mindate', true);
}
}
else {
route.$setValidity('maxdate', true);
route.$setValidity('mindate', true);
}
}
};
//////////////////////////////////////////////////
//Error elements
function getElementRequiredError(field, fieldName) {
var el = getErrorElem(getMessage('required_default_error'));
return el.attr('ng-class', '{\'show\': fieldRequiredError(' + getFormFieldRoute(fieldName) + ')}');
};
function getElementPatternError(field, fieldName, customMsg) {
var msg = customMsg !== undefined && customMsg != null ? customMsg : getMessage('pattern_default_error');
var el = getErrorElem(msg);
return el.attr('ng-class', '{\'show\': fieldPatternError(' + getFormFieldRoute(fieldName) + ')}');
};
function getElementMinLengthError(field, fieldName) {
var el = getErrorElem(getMessage('min_length_default_error') + ": " + getMinRange(field));
return el.attr('ng-class', '{\'show\': fieldMinLengthError(' + getFormFieldRoute(fieldName) + ')}');
};
function getElementMaxLengthError(field, fieldName) {
var el = getErrorElem(getMessage('max_length_default_error') + ": " + getMaxRange(field));
return el.attr('ng-class', '{\'show\': fieldMaxLengthError(' + getFormFieldRoute(fieldName) + ')}');
};
function getElementMinError(field, fieldName) {
var el = getErrorElem(getMessage('min_default_error') + ": " + getMinRange(field));
return el.attr('ng-class', '{\'show\': fieldMinError(' + getFormFieldRoute(fieldName) + ')}');
};
function getElementMaxError(field, fieldName) {
var el = getErrorElem(getMessage('max_default_error') + ": " + getMaxRange(field));
return el.attr('ng-class', '{\'show\': fieldMaxError(' + getFormFieldRoute(fieldName) + ')}');
};
function getElementMinDateError(field, fieldName) {
var el = getErrorElem(getMessage('min_date_default_error'));
return el.attr('ng-class', '{\'show\': fieldDateMinError(' + getFormFieldRoute(fieldName) + ')}');
};
function getElementMaxDateError(field, fieldName) {
var el = getErrorElem(getMessage('max_date_default_error'));
return el.attr('ng-class', '{\'show\': fieldDateMaxError(' + getFormFieldRoute(fieldName) + ')}');
};
function getMinRange(field) {
if (field.range.Min != undefined) {
return field.range.Min;
}
if (field.range.min != undefined) {
return field.range.min;
}
}
function getMaxRange(field) {
if (field.range.Max != undefined) {
return field.range.Max;
}
if (field.range.max != undefined) {
return field.range.max;
}
}
//Validation errors
$scope.fieldHasError = function (field) {
if (field !== undefined) {
return $scope.hasError(field);
}
};
$scope.fieldRequiredError = function (field) {
if (field !== undefined) {
return $scope.requiredError(field);
}
};
$scope.fieldPatternError = function (field) {
if (field !== undefined) {
return $scope.patternError(field);
}
};
$scope.fieldMinLengthError = function (field) {
if (field !== undefined) {
return $scope.minlengthError(field);
}
};
$scope.fieldMaxLengthError = function (field) {
if (field !== undefined) {
return $scope.maxlengthError(field);
}
};
$scope.fieldMinError = function (field) {
if (field !== undefined) {
return $scope.minError(field);
}
};
$scope.fieldMaxError = function (field) {
if (field !== undefined) {
return $scope.maxError(field);
}
};
$scope.fieldDateMinError = function (field) {
if (field !== undefined) {
return $scope.mindateError(field);
}
};
$scope.fieldDateMaxError = function (field) {
if (field !== undefined) {
return $scope.maxdateError(field);
}
};
},
};
});
})();
/*
jQuery UI Slider plugin wrapper
*/
angular.module('ui.slider', []).value('uiSliderConfig', {}).directive('uiSlider', ['uiSliderConfig', '$timeout', function (uiSliderConfig, $timeout) {
uiSliderConfig = uiSliderConfig || {};
return {
require: 'ngModel',
compile: function () {
var preLink = function (scope, elm, attrs, ngModel) {
function parseNumber(n, decimals) {
return (decimals) ? parseFloat(n) : parseInt(n, 10);
}
var directiveOptions = angular.copy(scope.$eval(attrs.uiSlider));
var options = angular.extend(directiveOptions || {}, uiSliderConfig);
// Object holding range values
var prevRangeValues = {
min: null,
max: null
};
// convenience properties
var properties = ['min', 'max', 'step', 'lowerBound', 'upperBound'];
var useDecimals = (!angular.isUndefined(attrs.useDecimals)) ? true : false;
var updateOn = (angular.isDefined(options['updateOn'])) ? options['updateOn'] : 'slide'
var init = function () {
// When ngModel is assigned an array of values then range is expected to be true.
// Warn user and change range to true else an error occurs when trying to drag handle
if (angular.isArray(ngModel.$viewValue) && options.range !== true) {
console.warn('Change your range option of ui-slider. When assigning ngModel an array of values then the range option should be set to true.');
options.range = true;
}
// Ensure the convenience properties are passed as options if they're defined
// This avoids init ordering issues where the slider's initial state (eg handle
// position) is calculated using widget defaults
// Note the properties take precedence over any duplicates in options
angular.forEach(properties, function (property) {
if (angular.isDefined(attrs[property])) {
options[property] = parseNumber(attrs[property], useDecimals);
}
});
elm.slider(options);
init = angular.noop;
};
// Find out if decimals are to be used for slider
angular.forEach(properties, function (property) {
// support {{}} and watch for updates
attrs.$observe(property, function (newVal) {
if (!!newVal) {
init();
options[property] = parseNumber(newVal, useDecimals);
elm.slider('option', property, parseNumber(newVal, useDecimals));
ngModel.$render();
}
});
});
attrs.$observe('disabled', function (newVal) {
init();
elm.slider('option', 'disabled', !!newVal);
});
// Watch ui-slider (byVal) for changes and update
scope.$watch(attrs.uiSlider, function (newVal) {
init();
if (newVal !== undefined) {
elm.slider('option', newVal);
}
}, true);
// Late-bind to prevent compiler clobbering
$timeout(init, 0, true);
// Update model value from slider
elm.bind(updateOn, function (event, ui) {
var valuesChanged;
if (ui.values) {
var boundedValues = ui.values.slice();
if (options.lowerBound && boundedValues[0] < options.lowerBound) {
boundedValues[0] = Math.max(boundedValues[0], options.lowerBound);
}
if (options.upperBound && boundedValues[1] > options.upperBound) {
boundedValues[1] = Math.min(boundedValues[1], options.upperBound);
}
if (boundedValues[0] !== ui.values[0] || boundedValues[1] !== ui.values[1]) {
valuesChanged = true;
ui.values = boundedValues;
}
} else {
var boundedValue = ui.value;
if (options.lowerBound && boundedValue < options.lowerBound) {
boundedValue = Math.max(boundedValue, options.lowerBound);
}
if (options.upperBound && boundedValue > options.upperBound) {
boundedValue = Math.min(boundedValue, options.upperBound);
}
if (boundedValue !== ui.value) {
valuesChanged = true;
ui.value = boundedValue;
}
}
ngModel.$setViewValue(ui.values || ui.value);
$(ui.handle).find('.ui-slider-tip').text(ui.value);
scope.$apply();
if (valuesChanged) {
setTimeout(function () {
elm.slider('value', ui.values || ui.value);
}, 0);
return false;
}
});
// Update slider from model value
ngModel.$render = function () {
init();
var method = options.range === true ? 'values' : 'value';
if (options.range !== true && isNaN(ngModel.$viewValue) && !(ngModel.$viewValue instanceof Array)) {
ngModel.$viewValue = 0;
}
else if (options.range && !angular.isDefined(ngModel.$viewValue)) {
ngModel.$viewValue = [0, 0];
}
// Do some sanity check of range values
if (options.range === true) {
// previously, the model was a string b/c it was in a text input, need to convert to a array.
// make sure input exists, comma exists once, and it is a string.
if (ngModel.$viewValue && angular.isString(ngModel.$viewValue) && (ngModel.$viewValue.match(/,/g) || []).length === 1) {
// transform string model into array.
var valueArr = ngModel.$viewValue.split(',');
ngModel.$viewValue = [Number(valueArr[0]), Number(valueArr[1])];
}
// Check outer bounds for min and max values
if (angular.isDefined(options.min) && options.min > ngModel.$viewValue[0]) {
ngModel.$viewValue[0] = options.min;
}
if (angular.isDefined(options.max) && options.max < ngModel.$viewValue[1]) {
ngModel.$viewValue[1] = options.max;
}
// Check min and max range values
if (ngModel.$viewValue[0] > ngModel.$viewValue[1]) {
// Min value should be less to equal to max value
if (prevRangeValues.min >= ngModel.$viewValue[1]) {
ngModel.$viewValue[1] = prevRangeValues.min;
}
// Max value should be less to equal to min value
if (prevRangeValues.max <= ngModel.$viewValue[0]) {
ngModel.$viewValue[0] = prevRangeValues.max;
}
}
// Store values for later user
prevRangeValues.min = ngModel.$viewValue[0];
prevRangeValues.max = ngModel.$viewValue[1];
}
elm.slider(method, ngModel.$viewValue);
};
scope.$watch(attrs.ngModel, function () {
if (options.range === true) {
ngModel.$render();
$(elm).find('.ui-slider-tip').each(function (i, tipElm) {
$(tipElm).text(ngModel.$viewValue[i]);
});
} else {
$(elm).find('.ui-slider-tip').text(ngModel.$viewValue);
}
}, true);
function destroy() {
if (elm.hasClass('ui-slider')) {
elm.slider('destroy');
}
}
scope.$on("$destroy", destroy);
elm.one('$destroy', destroy);
};
var postLink = function (scope, element, attrs, ngModel) {
// Add tick marks if 'tick' and 'step' attributes have been setted on element.
// Support horizontal slider bar so far. 'tick' and 'step' attributes are required.
var options = angular.extend({}, scope.$eval(attrs.uiSlider));
var properties = ['min', 'max', 'step', 'tick', 'tip'];
angular.forEach(properties, function (property) {
if (angular.isDefined(attrs[property])) {
options[property] = attrs[property];
}
});
if (angular.isDefined(options['tick']) && angular.isDefined(options['step'])) {
var total = parseInt((parseInt(options['max']) - parseInt(options['min'])) / parseInt(options['step']));
for (var i = total; i >= 0; i--) {
var left = ((i / total) * 100) + '%';
$("
").addClass("ui-slider-tick").appendTo(element).css({ left: left });
};
}
if (angular.isDefined(options['tip'])) {
$timeout(function () {
var handles = element.find('.ui-slider-handle');
if (handles && handles.length > 1 && ngModel.$viewValue && angular.isArray(ngModel.$viewValue)) {
$(handles[0]).append('
' + ngModel.$viewValue[0] + '
');
$(handles[1]).append('
' + ngModel.$viewValue[1] + '
');
} else {
element.find('.ui-slider-handle').append('
' + ngModel.$viewValue + '
');
}
}, 10);
}
}
return {
pre: preLink,
post: postLink
};
}
};
}]);
angular.module('ngLazyImage', []);
angular.module('ngLazyImage')
.service('afklSrcSetService', ['$window', function ($window) {
'use strict';
/**
* For other applications wanting the srccset/best image approach it is possible to use this module only
* Loosely based on https://raw.github.com/borismus/srcset-polyfill/master/js/srcset-info.js
*/
var INT_REGEXP = /^[0-9]+$/;
// SRCSET IMG OBJECT
function ImageInfo(options) {
this.src = options.src;
this.w = options.w || Infinity;
this.h = options.h || Infinity;
this.x = options.x || 1;
}
/**
* Parse srcset rules
* @param {string} descString Containing all srcset rules
* @return {object} Srcset rules
*/
var _parseDescriptors = function (descString) {
var descriptors = descString.split(/\s/);
var out = {};
for (var i = 0, l = descriptors.length; i < l; i++) {
var desc = descriptors[i];
if (desc.length > 0) {
var lastChar = desc.slice(-1);
var value = desc.substring(0, desc.length - 1);
var intVal = parseInt(value, 10);
var floatVal = parseFloat(value);
if (value.match(INT_REGEXP) && lastChar === 'w') {
out[lastChar] = intVal;
} else if (value.match(INT_REGEXP) && lastChar === 'h') {
out[lastChar] = intVal;
} else if (!isNaN(floatVal) && lastChar === 'x') {
out[lastChar] = floatVal;
}
}
}
return out;
};
/**
* Returns best candidate under given circumstances
* @param {object} images Candidate image
* @param {function} criteriaFn Rule
* @return {object} Returns best candidate under given criteria
*/
var _getBestCandidateIf = function (images, criteriaFn) {
var bestCandidate = images[0];
for (var i = 0, l = images.length; i < l; i++) {
var candidate = images[i];
if (criteriaFn(candidate, bestCandidate)) {
bestCandidate = candidate;
}
}
return bestCandidate;
};
/**
* Remove candidate under given circumstances
* @param {object} images Candidate image
* @param {function} criteriaFn Rule
* @return {object} Removes images from global image collection (candidates)
*/
var _removeCandidatesIf = function (images, criteriaFn) {
for (var i = images.length - 1; i >= 0; i--) {
var candidate = images[i];
if (criteriaFn(candidate)) {
images.splice(i, 1); // remove it
}
}
return images;
};
/**
* Direct implementation of "processing the image candidates":
* http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-1.html#processing-the-image-candidates
*
* @param {array} imageCandidates (required)
* @param {object} view (optional)
* @returns {ImageInfo} The best image of the possible candidates.
*/
var getBestImage = function (imageCandidates, view) {
if (!imageCandidates) { return; }
if (!view) {
view = {
'w': $window.innerWidth || document.documentElement.clientWidth,
'h': $window.innerHeight || document.documentElement.clientHeight,
'x': $window.devicePixelRatio || 1
};
}
var images = imageCandidates.slice(0);
/* LARGEST */
// Width
var largestWidth = _getBestCandidateIf(images, function (a, b) { return a.w > b.w; });
// Less than client width.
_removeCandidatesIf(images, (function () { return function (a) { return a.w < view.w; }; })(this));
// If none are left, keep the one with largest width.
if (images.length === 0) { images = [largestWidth]; }
// Height
var largestHeight = _getBestCandidateIf(images, function (a, b) { return a.h > b.h; });
// Less than client height.
_removeCandidatesIf(images, (function () { return function (a) { return a.h < view.h; }; })(this));
// If none are left, keep one with largest height.
if (images.length === 0) { images = [largestHeight]; }
// Pixel density.
var largestPxDensity = _getBestCandidateIf(images, function (a, b) { return a.x > b.x; });
// Remove all candidates with pxdensity less than client pxdensity.
_removeCandidatesIf(images, (function () { return function (a) { return a.x < view.x; }; })(this));
// If none are left, keep one with largest pixel density.
if (images.length === 0) { images = [largestPxDensity]; }
/* SMALLEST */
// Width
var smallestWidth = _getBestCandidateIf(images, function (a, b) { return a.w < b.w; });
// Remove all candidates with width greater than it.
_removeCandidatesIf(images, function (a) { return a.w > smallestWidth.w; });
// Height
var smallestHeight = _getBestCandidateIf(images, function (a, b) { return a.h < b.h; });
// Remove all candidates with height greater than it.
_removeCandidatesIf(images, function (a) { return a.h > smallestHeight.h; });
// Pixel density
var smallestPxDensity = _getBestCandidateIf(images, function (a, b) { return a.x < b.x; });
// Remove all candidates with pixel density less than smallest px density.
_removeCandidatesIf(images, function (a) { return a.x > smallestPxDensity.x; });
return images[0];
};
// options {src: null/string, srcset: string}
// options.src normal url or null
// options.srcset 997-s.jpg 480w, 997-m.jpg 768w, 997-xl.jpg 1x
var getSrcset = function (options) {
var imageCandidates = [];
var srcValue = options.src;
var srcsetValue = options.srcset;
if (!srcsetValue) { return; }
/* PUSH CANDIDATE [{src: _, x: _, w: _, h:_}, ...] */
var _addCandidate = function (img) {
for (var j = 0, ln = imageCandidates.length; j < ln; j++) {
var existingCandidate = imageCandidates[j];
// DUPLICATE
if (existingCandidate.x === img.x &&
existingCandidate.w === img.w &&
existingCandidate.h === img.h) { return; }
}
imageCandidates.push(img);
};
var _parse = function () {
var input = srcsetValue,
position = 0,
rawCandidates = [],
url,
descriptors;
while (input !== '') {
while (input.charAt(0) === ' ') {
input = input.slice(1);
}
position = input.indexOf(' ');
if (position !== -1) {
url = input.slice(0, position);
// if (url === '') { break; }
input = input.slice(position + 1);
position = input.indexOf(',');
if (position === -1) {
descriptors = input;
input = '';
} else {
descriptors = input.slice(0, position);
input = input.slice(position + 1);
}
rawCandidates.push({
url: url,
descriptors: descriptors
});
} else {
rawCandidates.push({
url: input,
descriptors: ''
});
input = '';
}
}
// FROM RAW CANDIDATES PUSH IMAGES TO COMPLETE SET
for (var i = 0, l = rawCandidates.length; i < l; i++) {
var candidate = rawCandidates[i],
desc = _parseDescriptors(candidate.descriptors);
_addCandidate(new ImageInfo({
src: candidate.url,
x: desc.x,
w: desc.w,
h: desc.h
}));
}
if (srcValue) {
_addCandidate(new ImageInfo({ src: srcValue }));
}
};
_parse();
// Return best available image for current view based on our list of candidates
var bestImage = getBestImage(imageCandidates);
/**
* Object returning best match at moment, and total collection of candidates (so 'image' API can be used by consumer)
* @type {Object}
*/
var object = {
'best': bestImage, // IMAGE INFORMATION WHICH FITS BEST WHEN API IS REQUESTED
'candidates': imageCandidates // ALL IMAGE CANDIDATES BY GIVEN SRCSET ATTRIBUTES
};
// empty collection
imageCandidates = null;
// pass best match and candidates
return object;
};
// throttle function to be used in directive
function throttle(callback, delay) {
var last, deferTimer;
return function () {
var now = +new Date();
if (last && now < last + delay) {
clearTimeout(deferTimer);
deferTimer = setTimeout(function () {
last = now;
callback();
}, delay + last - now);
} else {
last = now;
callback();
}
};
}
/**
* PUBLIC API
*/
return {
get: getSrcset, // RETURNS BEST IMAGE AND IMAGE CANDIDATES
image: getBestImage, // RETURNS BEST IMAGE WITH GIVEN CANDIDATES
throttle: throttle // RETURNS A THROTTLER FUNCTION
};
}]);
angular.module('ngLazyImage')
.directive('afklImageContainer', function () {
'use strict';
return {
restrict: 'A',
// We have to use controller instead of link here so that it will always run earlier than nested afklLazyImage directives
controller: ['$scope', '$element', function ($scope, $element) {
$element.data('afklImageContainer', $element);
}]
};
})
.directive('afklLazyImage', ['$rootScope', '$window', '$timeout', 'afklSrcSetService', '$parse', function ($rootScope, $window, $timeout, srcSetService, $parse) {
'use strict';
// Use srcSetService to find out our best available image
var bestImage = function (images) {
var image = srcSetService.get({ srcset: images });
var sourceUrl;
if (image) {
sourceUrl = image.best.src;
}
return sourceUrl;
};
return {
restrict: 'A',
link: function (scope, element, attrs) {
var _concatImgAttrs = function (imgAttrs) {
var result = [];
var CLASSNAME = 'afkl-lazy-image';
var setClass = false;
if (!!options.imgAttrs) {
result = Array.prototype.map.call(imgAttrs, function (item) {
for (var key in item) {
if (item.hasOwnProperty(key)) {
// TODO: TITLE CAN COME LATER (FROM DATA MODEL)
var value = item[key];
if (key === 'class') {
setClass = true;
value = value + ' ' + CLASSNAME;
}
return String.prototype.concat.call(key, '="', value, '"');
}
}
});
}
if (!setClass) {
result.push('class="' + CLASSNAME + '"');
}
return result.join(' ');
};
// CONFIGURATION VARS
var $container = element.inheritedData('afklImageContainer');
if (!$container) {
$container = angular.element(attrs.afklLazyImageContainer || $window);
}
var loaded = false;
var timeout;
var images = attrs.afklLazyImage; // srcset attributes
var options = attrs.afklLazyImageOptions ? $parse(attrs.afklLazyImageOptions)(scope) : {}; // options (background, offset)
var img = null; // Angular element to image which will be placed
var currentImage = null; // current image url
var offset = options.offset ? options.offset : 50; // default offset
var imgAttrs = _concatImgAttrs(options.imgAttrs); // all image attributes like class, title, onerror
var LOADING = 'afkl-lazy-image-loading';
attrs.afklLazyImageLoaded = false;
var _containerScrollTop = function () {
// See if we can use jQuery, with extra check
// TODO: check if number is returned
if ($container.scrollTop) {
var scrollTopPosition = $container.scrollTop();
if (scrollTopPosition) {
return scrollTopPosition;
}
}
var c = $container[0];
if (c.pageYOffset !== undefined) {
return c.pageYOffset;
}
else if (c.scrollTop !== undefined) {
return c.scrollTop;
}
return document.documentElement.scrollTop || 0;
};
var _containerInnerHeight = function () {
if ($container.innerHeight) {
return $container.innerHeight();
}
var c = $container[0];
if (c.innerHeight !== undefined) {
return c.innerHeight;
} else if (c.clientHeight !== undefined) {
return c.clientHeight;
}
return document.documentElement.clientHeight || 0;
};
// Begin with offset and update on resize
var _elementOffset = function () {
if (element.offset) {
return element.offset().top;
}
var box = element[0].getBoundingClientRect();
return box.top + _containerScrollTop() - document.documentElement.clientTop;
};
var _elementOffsetContainer = function () {
if (element.offset) {
return element.offset().top - $container.offset().top;
}
return element[0].getBoundingClientRect().top - $container[0].getBoundingClientRect().top;
};
// Update url of our image
var _setImage = function () {
if (options.background) {
element[0].style.backgroundImage = 'url("' + currentImage + '")';
} else if (!!img) {
img[0].src = currentImage;
}
};
// Append image to DOM
var _placeImage = function () {
loaded = true;
// What is my best image available
var hasImage = bestImage(images);
if (hasImage) {
// we have to make an image if background is false (default)
if (!options.background) {
if (!img) {
element.addClass(LOADING);
img = angular.element('
');
img.one('load', _loaded);
img.one('error', _error);
// remove loading class when image is acually loaded
element.append(img);
}
}
// set correct src/url
_checkIfNewImage();
}
// Element is added to dom, no need to listen to scroll anymore
$container.off('scroll', _onViewChange);
};
// Check on resize if actually a new image is best fit, if so then apply it
var _checkIfNewImage = function () {
if (loaded) {
var newImage = bestImage(images);
if (newImage !== currentImage) {
// update current url
currentImage = newImage;
// TODO: loading state...
// update image url
_setImage();
}
}
};
// First update our begin offset
_checkIfNewImage();
var _loaded = function () {
attrs.$set('afklLazyImageLoaded', 'done');
element.removeClass(LOADING);
};
var _error = function () {
attrs.$set('afklLazyImageLoaded', 'fail');
};
// Check if the container is in view for the first time. Utilized by the scroll and resize events.
var _onViewChange = function () {
// only do stuff when not set already
if (!loaded) {
// Config vars
var remaining, shouldLoad, windowBottom;
var height = _containerInnerHeight();
var scroll = _containerScrollTop();
var elOffset = $container[0] === $window ? _elementOffset() : _elementOffsetContainer();
windowBottom = $container[0] === $window ? height + scroll : height;
remaining = elOffset - windowBottom;
// Is our top of our image container in bottom of our viewport?
//console.log($container[0].className, _elementOffset(), _elementPosition(), height, scroll, remaining, elOffset);
shouldLoad = remaining <= offset;
// Append image first time when it comes into our view, after that only resizing can have influence
if (shouldLoad) {
_placeImage();
}
}
};
var _onViewChangeThrottled = srcSetService.throttle(_onViewChange, 300);
// EVENT: RESIZE THROTTLED
var _onResize = function () {
$timeout.cancel(timeout);
timeout = $timeout(function () {
_checkIfNewImage();
_onViewChange();
}, 300);
};
// Remove events for total destroy
var _eventsOff = function () {
$timeout.cancel(timeout);
angular.element($window).off('resize', _onResize);
angular.element($window).off('scroll', _onViewChangeThrottled);
if ($container[0] !== $window) {
$container.off('resize', _onResize);
$container.off('scroll', _onViewChangeThrottled);
}
// remove image being placed
if (img) {
img.remove();
}
img = timeout = currentImage = undefined;
};
// set events for scrolling and resizing on window
// even if container is not window it is important
// to cover two cases:
// - when container size is bigger than window's size
// - when container's side is out of initial window border
angular.element($window).on('resize', _onResize);
angular.element($window).on('scroll', _onViewChangeThrottled);
// if container is not window, set events for container as well
if ($container[0] !== $window) {
$container.on('resize', _onResize);
$container.on('scroll', _onViewChangeThrottled);
}
// events for image change
attrs.$observe('afklLazyImage', function () {
images = attrs.afklLazyImage;
if (loaded) {
_placeImage();
}
});
// Image should be directly placed
if (options.nolazy) {
_placeImage();
}
scope.$on('afkl.lazyImage.destroyed', _onResize);
// Remove all events when destroy takes place
scope.$on('$destroy', function () {
// tell our other kids, i got removed
$rootScope.$broadcast('afkl.lazyImage.destroyed');
// remove our events and image
return _eventsOff();
});
return _onViewChange();
}
};
}]);
/*
AngularJS v1.4.5
(c) 2010-2015 Google, Inc. http://angularjs.org
License: MIT
*/
(function(x,s,y){'use strict';function t(f,k,p){n.directive(f,["$parse","$swipe",function(c,e){return function(l,m,g){function h(a){if(!b)return!1;var d=Math.abs(a.y-b.y);a=(a.x-b.x)*k;return r&&75>d&&0
d/a}var d=c(g[f]),b,r,a=["touch"];s.isDefined(g.ngSwipeDisableMouse)||a.push("mouse");e.bind(m,{start:function(a,d){b=a;r=!0},cancel:function(a){r=!1},end:function(a,b){h(a)&&l.$apply(function(){m.triggerHandler(p);d(l,{$event:b})})}},a)}}])}var n=s.module("ngTouch",[]);n.factory("$swipe",
[function(){function f(c){c=c.originalEvent||c;var e=c.touches&&c.touches.length?c.touches:[c];c=c.changedTouches&&c.changedTouches[0]||e[0];return{x:c.clientX,y:c.clientY}}function k(c,e){var l=[];s.forEach(c,function(c){(c=p[c][e])&&l.push(c)});return l.join(" ")}var p={mouse:{start:"mousedown",move:"mousemove",end:"mouseup"},touch:{start:"touchstart",move:"touchmove",end:"touchend",cancel:"touchcancel"}};return{bind:function(c,e,l){var m,g,h,d,b=!1;l=l||["mouse","touch"];c.on(k(l,"start"),function(a){h=
f(a);b=!0;g=m=0;d=h;e.start&&e.start(h,a)});var r=k(l,"cancel");if(r)c.on(r,function(a){b=!1;e.cancel&&e.cancel(a)});c.on(k(l,"move"),function(a){if(b&&h){var c=f(a);m+=Math.abs(c.x-d.x);g+=Math.abs(c.y-d.y);d=c;10>m&&10>g||(g>m?(b=!1,e.cancel&&e.cancel(a)):(a.preventDefault(),e.move&&e.move(c,a)))}});c.on(k(l,"end"),function(a){b&&(b=!1,e.end&&e.end(f(a),a))})}}}]);n.config(["$provide",function(f){f.decorator("ngClickDirective",["$delegate",function(k){k.shift();return k}])}]);n.directive("ngClick",
["$parse","$timeout","$rootElement",function(f,k,p){function c(d,b,c){for(var a=0;aMath.abs(d[a]-b)&&25>Math.abs(e-g))return d.splice(a,a+2),!0}return!1}function e(d){if(!(2500e&&1>b||h&&h[0]===e&&h[1]===b)){h&&(h=null);var a=d.target;"label"===s.lowercase(a.nodeName||a[0]&&a[0].nodeName)&&(h=[e,b]);c(g,e,b)||(d.stopPropagation(),d.preventDefault(),d.target&&
d.target.blur&&d.target.blur())}}}function l(d){d=d.touches&&d.touches.length?d.touches:[d];var b=d[0].clientX,c=d[0].clientY;g.push(b,c);k(function(){for(var a=0;ad&&12>w&&(g||(p[0].addEventListener("click",e,!0),p[0].addEventListener("touchstart",l,!0),g=[]),m=Date.now(),c(g,f,u),q&&q.blur(),s.isDefined(h.disabled)&&
!1!==h.disabled||b.triggerHandler("click",[a]));k=!1;b.removeClass("ng-click-active")});b.onclick=function(a){};b.on("click",function(b,c){d.$apply(function(){a(d,{$event:c||b})})});b.on("mousedown",function(a){b.addClass("ng-click-active")});b.on("mousemove mouseup",function(a){b.removeClass("ng-click-active")})}}]);t("ngSwipeLeft",-1,"swipeleft");t("ngSwipeRight",1,"swiperight")})(window,window.angular);
//# sourceMappingURL=angular-touch.min.js.map
/*global angular */
/*
Angular touch carousel with CSS GPU accel and slide buffering
http://github.com/revolunet/angular-carousel
*/
angular.module('angular-carousel', [
'ngTouch',
'angular-carousel.shifty'
]);
angular.module('angular-carousel')
.directive('rnCarouselAutoSlide', ['$interval', function($interval) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var stopAutoPlay = function() {
if (scope.autoSlider) {
$interval.cancel(scope.autoSlider);
scope.autoSlider = null;
}
};
var restartTimer = function() {
scope.autoSlide();
};
scope.$watch('carouselIndex', restartTimer);
if (attrs.hasOwnProperty('rnCarouselPauseOnHover') && attrs.rnCarouselPauseOnHover !== 'false'){
element.on('mouseenter', stopAutoPlay);
element.on('mouseleave', restartTimer);
}
scope.$on('$destroy', function(){
stopAutoPlay();
element.off('mouseenter', stopAutoPlay);
element.off('mouseleave', restartTimer);
});
}
};
}]);
angular.module('angular-carousel')
.directive('rnCarouselIndicators', ['$parse', function($parse) {
return {
restrict: 'A',
scope: {
slides: '=',
index: '=rnCarouselIndex',
visibleItems: '='
},
templateUrl: 'carousel-indicators.html',
link: function(scope, iElement, iAttributes) {
var indexModel = $parse(iAttributes.rnCarouselIndex);
scope.goToSlide = function(index) {
indexModel.assign(scope.$parent.$parent, index);
};
}
};
}]);
angular.module('angular-carousel').run(['$templateCache', function($templateCache) {
$templateCache.put('carousel-indicators.html',
'\n' +
'● ' +
'
'
);
}]);
(function() {
"use strict";
angular.module('angular-carousel')
.service('DeviceCapabilities', function() {
// TODO: merge in a single function
// detect supported CSS property
function detectTransformProperty() {
var transformProperty = 'transform',
safariPropertyHack = 'webkitTransform';
if (typeof document.body.style[transformProperty] !== 'undefined') {
['webkit', 'moz', 'o', 'ms'].every(function (prefix) {
var e = '-' + prefix + '-transform';
if (typeof document.body.style[e] !== 'undefined') {
transformProperty = e;
return false;
}
return true;
});
} else if (typeof document.body.style[safariPropertyHack] !== 'undefined') {
transformProperty = '-webkit-transform';
} else {
transformProperty = undefined;
}
return transformProperty;
}
//Detect support of translate3d
function detect3dSupport() {
var el = document.createElement('p'),
has3d,
transforms = {
'webkitTransform': '-webkit-transform',
'msTransform': '-ms-transform',
'transform': 'transform'
};
// Add it to the body to get the computed style
document.body.insertBefore(el, null);
for (var t in transforms) {
if (el.style[t] !== undefined) {
el.style[t] = 'translate3d(1px,1px,1px)';
has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
}
}
document.body.removeChild(el);
return (has3d !== undefined && has3d.length > 0 && has3d !== "none");
}
return {
has3d: detect3dSupport(),
transformProperty: detectTransformProperty()
};
})
.service('computeCarouselSlideStyle', function(DeviceCapabilities) {
// compute transition transform properties for a given slide and global offset
return function(slideIndex, offset, transitionType) {
var style = {
display: 'inline-block'
},
opacity,
absoluteLeft = (slideIndex * 100) + offset,
slideTransformValue = DeviceCapabilities.has3d ? 'translate3d(' + absoluteLeft + '%, 0, 0)' : 'translate3d(' + absoluteLeft + '%, 0)',
distance = ((100 - Math.abs(absoluteLeft)) / 100);
if (!DeviceCapabilities.transformProperty) {
// fallback to default slide if transformProperty is not available
style['margin-left'] = absoluteLeft + '%';
} else {
if (transitionType == 'fadeAndSlide') {
style[DeviceCapabilities.transformProperty] = slideTransformValue;
opacity = 0;
if (Math.abs(absoluteLeft) < 100) {
opacity = 0.3 + distance * 0.7;
}
style.opacity = opacity;
} else if (transitionType == 'hexagon') {
var transformFrom = 100,
degrees = 0,
maxDegrees = 60 * (distance - 1);
transformFrom = offset < (slideIndex * -100) ? 100 : 0;
degrees = offset < (slideIndex * -100) ? maxDegrees : -maxDegrees;
style[DeviceCapabilities.transformProperty] = slideTransformValue + ' ' + 'rotateY(' + degrees + 'deg)';
style[DeviceCapabilities.transformProperty + '-origin'] = transformFrom + '% 50%';
} else if (transitionType == 'zoom') {
style[DeviceCapabilities.transformProperty] = slideTransformValue;
var scale = 1;
if (Math.abs(absoluteLeft) < 100) {
scale = 1 + ((1 - distance) * 2);
}
style[DeviceCapabilities.transformProperty] += ' scale(' + scale + ')';
style[DeviceCapabilities.transformProperty + '-origin'] = '50% 50%';
opacity = 0;
if (Math.abs(absoluteLeft) < 100) {
opacity = 0.3 + distance * 0.7;
}
style.opacity = opacity;
} else {
style[DeviceCapabilities.transformProperty] = slideTransformValue;
}
}
return style;
};
})
.service('createStyleString', function() {
return function(object) {
var styles = [];
angular.forEach(object, function(value, key) {
styles.push(key + ':' + value);
});
return styles.join(';');
};
})
.directive('rnCarousel', ['$swipe', '$window', '$document', '$parse', '$compile', '$timeout', '$interval', 'computeCarouselSlideStyle', 'createStyleString', 'Tweenable',
function($swipe, $window, $document, $parse, $compile, $timeout, $interval, computeCarouselSlideStyle, createStyleString, Tweenable) {
// internal ids to allow multiple instances
var carouselId = 0,
// in absolute pixels, at which distance the slide stick to the edge on release
rubberTreshold = 3;
var requestAnimationFrame = $window.requestAnimationFrame || $window.webkitRequestAnimationFrame || $window.mozRequestAnimationFrame;
function getItemIndex(collection, target, defaultIndex) {
var result = defaultIndex;
collection.every(function(item, index) {
if (angular.equals(item, target)) {
result = index;
return false;
}
return true;
});
return result;
}
return {
restrict: 'A',
scope: true,
compile: function(tElement, tAttributes) {
// use the compile phase to customize the DOM
var firstChild = tElement[0].querySelector('li'),
firstChildAttributes = (firstChild) ? firstChild.attributes : [],
isRepeatBased = false,
isBuffered = false,
repeatItem,
repeatCollection;
// try to find an ngRepeat expression
// at this point, the attributes are not yet normalized so we need to try various syntax
['ng-repeat', 'data-ng-repeat', 'ng:repeat', 'x-ng-repeat'].every(function(attr) {
var repeatAttribute = firstChildAttributes[attr];
if (angular.isDefined(repeatAttribute)) {
// ngRepeat regexp extracted from angular 1.2.7 src
var exprMatch = repeatAttribute.value.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),
trackProperty = exprMatch[3];
repeatItem = exprMatch[1];
repeatCollection = exprMatch[2];
if (repeatItem) {
if (angular.isDefined(tAttributes['rnCarouselBuffered'])) {
// update the current ngRepeat expression and add a slice operator if buffered
isBuffered = true;
repeatAttribute.value = repeatItem + ' in ' + repeatCollection + '|carouselSlice:carouselBufferIndex:carouselBufferSize';
if (trackProperty) {
repeatAttribute.value += ' track by ' + trackProperty;
}
}
isRepeatBased = true;
return false;
}
}
return true;
});
return function(scope, iElement, iAttributes, containerCtrl) {
carouselId++;
var defaultOptions = {
transitionType: iAttributes.rnCarouselTransition || 'slide',
transitionEasing: iAttributes.rnCarouselEasing || 'easeTo',
transitionDuration: parseInt(iAttributes.rnCarouselDuration, 10) || 300,
isSequential: true,
autoSlideDuration: 3,
bufferSize: 5,
/* in container % how much we need to drag to trigger the slide change */
moveTreshold: 0.1,
defaultIndex: 0
};
// TODO
var options = angular.extend({}, defaultOptions);
var pressed,
startX,
isIndexBound = false,
offset = 0,
destination,
swipeMoved = false,
//animOnIndexChange = true,
currentSlides = [],
elWidth = null,
elX = null,
animateTransitions = true,
intialState = true,
animating = false,
mouseUpBound = false,
locked = false;
//rn-swipe-disabled =true will only disable swipe events
if(iAttributes.rnSwipeDisabled !== "true") {
$swipe.bind(iElement, {
start: swipeStart,
move: swipeMove,
end: swipeEnd,
cancel: function(event) {
swipeEnd({}, event);
}
});
}
function getSlidesDOM() {
var nodes = iElement[0].childNodes;
var slides = [];
for(var i=0; i currentSlides.length - 1) {
index = 0;
}
if (!locked) {
goToSlide(index, slideOptions);
}
};
scope.prevSlide = function(slideOptions) {
var index = scope.carouselIndex - 1;
if (index < 0) {
index = currentSlides.length - 1;
}
goToSlide(index, slideOptions);
};
function goToSlide(index, slideOptions) {
//console.log('goToSlide', arguments);
// move a to the given slide index
if (index === undefined) {
index = scope.carouselIndex;
}
slideOptions = slideOptions || {};
if (slideOptions.animate === false || options.transitionType === 'none') {
locked = false;
offset = index * -100;
scope.carouselIndex = index;
updateBufferIndex();
return;
}
locked = true;
var tweenable = new Tweenable();
tweenable.tween({
from: {
'x': offset
},
to: {
'x': index * -100
},
duration: options.transitionDuration,
easing: options.transitionEasing,
step: function(state) {
if (isFinite(state.x)) {
updateSlidesPosition(state.x);
}
},
finish: function() {
scope.$apply(function() {
scope.carouselIndex = index;
offset = index * -100;
updateBufferIndex();
$timeout(function () {
locked = false;
}, 0, false);
});
}
});
}
scope.mouseLeave = function (selectControl) {
$('.item.active .preview-' + selectControl).addClass("out");
$('.item.active .preview-' + selectControl).removeClass("in");
$('.item.active .preview-' + selectControl).css('display', 'none');
}
scope.mouseEnter = function (selectControl) {
$('.item.active .preview-' + selectControl).css('display', 'flex');
setTimeout(function () {
$('.item.active .preview-' + selectControl).removeClass("out");
$('.item.active .preview-' + selectControl).addClass("in");
}, 10);
}
function getContainerWidth() {
var rect = iElement[0].getBoundingClientRect();
return rect.width ? rect.width : rect.right - rect.left;
}
function updateContainerWidth() {
elWidth = getContainerWidth();
}
function bindMouseUpEvent() {
if (!mouseUpBound) {
mouseUpBound = true;
$document.bind('mouseup', documentMouseUpEvent);
}
}
function unbindMouseUpEvent() {
if (mouseUpBound) {
mouseUpBound = false;
$document.unbind('mouseup', documentMouseUpEvent);
}
}
function swipeStart(coords, event) {
// console.log('swipeStart', coords, event);
if (locked || currentSlides.length <= 1) {
return;
}
updateContainerWidth();
elX = iElement[0].querySelector('li').getBoundingClientRect().left;
pressed = true;
startX = coords.x;
return false;
}
function swipeMove(coords, event) {
//console.log('swipeMove', coords, event);
var x, delta;
bindMouseUpEvent();
if (pressed) {
x = coords.x;
delta = startX - x;
if (delta > 2 || delta < -2) {
swipeMoved = true;
var moveOffset = offset + (-delta * 100 / elWidth);
updateSlidesPosition(moveOffset);
}
}
return false;
}
var init = true;
scope.carouselIndex = 0;
if (!isRepeatBased) {
// fake array when no ng-repeat
currentSlides = [];
angular.forEach(getSlidesDOM(), function(node, index) {
currentSlides.push({id: index});
});
if (iAttributes.rnCarouselHtmlSlides) {
var updateParentSlides = function(value) {
slidesModel.assign(scope.$parent, value);
};
var slidesModel = $parse(iAttributes.rnCarouselHtmlSlides);
if (angular.isFunction(slidesModel.assign)) {
/* check if this property is assignable then watch it */
scope.$watch('htmlSlides', function(newValue) {
updateParentSlides(newValue);
});
scope.$parent.$watch(slidesModel, function(newValue, oldValue) {
if (newValue !== undefined && newValue !== null) {
newValue = 0;
updateParentIndex(newValue);
}
});
}
scope.htmlSlides = currentSlides;
}
}
if (iAttributes.rnCarouselControls !== undefined) {
if (iAttributes.previewitems !== undefined) {
var previewItemsPrev = 'ng-mouseleave="mouseLeave(\'prev\')" ng-mouseover="mouseEnter(\'prev\')"';
var previewItemsNext = 'ng-mouseleave="mouseLeave(\'next\')" ng-mouseover="mouseEnter(\'next\')"';
} else {
var previewItemsPrev = '';
var previewItemsNext = '';
}
if (iAttributes.visibleItems !== undefined) {
var visibleItems = iAttributes.visibleItems;
} else {
var visibleItems = 1;
}
var textPrev = '';
var textNext = '';
var loadingControl = false;
if (iAttributes.textPrev !== undefined) textPrev = iAttributes.textPrev;
if (iAttributes.textNext != undefined) textNext = iAttributes.textNext;
if (iAttributes.rnCarouselLoading != undefined) loadingControl = iAttributes.rnCarouselLoading;
var canloop = ((isRepeatBased ? scope.$eval(repeatCollection.replace('::', '')).length : currentSlides.length) > 1) ? angular.isDefined(tAttributes['rnCarouselControlsAllowLoop']) : false;
var nextSlideIndexCompareValue = isRepeatBased ? '(' + repeatCollection.replace('::', '') + ').length - ' + visibleItems : currentSlides.length - visibleItems;
var tpl = '\n' +
' \n' +
' \n' +
' ' +
'
';
iElement.parent().append($compile(angular.element(tpl))(scope));
}
if (iAttributes.rnCarouselAutoSlide!==undefined) {
var duration = parseInt(iAttributes.rnCarouselAutoSlide, 10) || options.autoSlideDuration;
scope.autoSlide = function() {
if (scope.autoSlider) {
$interval.cancel(scope.autoSlider);
scope.autoSlider = null;
}
scope.autoSlider = $interval(function() {
if (!locked && !pressed) {
scope.nextSlide();
}
}, duration * 1000);
};
}
if (iAttributes.rnCarouselDefaultIndex) {
var defaultIndexModel = $parse(iAttributes.rnCarouselDefaultIndex);
options.defaultIndex = defaultIndexModel(scope.$parent) || 0;
}
if (iAttributes.rnCarouselIndex) {
var updateParentIndex = function(value) {
indexModel.assign(scope.$parent, value);
};
var indexModel = $parse(iAttributes.rnCarouselIndex);
if (angular.isFunction(indexModel.assign)) {
/* check if this property is assignable then watch it */
scope.$watch('carouselIndex', function(newValue) {
updateParentIndex(newValue);
});
scope.$parent.$watch(indexModel, function(newValue, oldValue) {
if (newValue !== undefined && newValue !== null) {
if (currentSlides && currentSlides.length > 0 && newValue >= currentSlides.length) {
newValue = currentSlides.length - 1;
updateParentIndex(newValue);
} else if (currentSlides && newValue < 0) {
newValue = 0;
updateParentIndex(newValue);
}
if (!locked) {
goToSlide(newValue, {
animate: !init
});
}
init = false;
}
});
isIndexBound = true;
if (options.defaultIndex) {
goToSlide(options.defaultIndex, {
animate: !init
});
}
} else if (!isNaN(iAttributes.rnCarouselIndex)) {
/* if user just set an initial number, set it */
goToSlide(parseInt(iAttributes.rnCarouselIndex, 10), {
animate: false
});
}
} else {
goToSlide(options.defaultIndex, {
animate: !init
});
init = false;
}
if (iAttributes.rnCarouselLocked) {
scope.$watch(iAttributes.rnCarouselLocked, function(newValue, oldValue) {
// only bind swipe when it's not switched off
if(newValue === true) {
locked = true;
} else {
locked = false;
}
});
}
if (isRepeatBased) {
// use rn-carousel-deep-watch to fight the Angular $watchCollection weakness : https://github.com/angular/angular.js/issues/2621
// optional because it have some performance impacts (deep watch)
var deepWatch = (iAttributes.rnCarouselDeepWatch!==undefined);
scope[deepWatch?'$watch':'$watchCollection'](repeatCollection, function(newValue, oldValue) {
//console.log('repeatCollection', currentSlides);
currentSlides = newValue;
// if deepWatch ON ,manually compare objects to guess the new position
if (!angular.isArray(currentSlides)) {
throw Error('the slides collection must be an Array');
}
if (deepWatch && angular.isArray(newValue)) {
var activeElement = oldValue[scope.carouselIndex];
var newIndex = getItemIndex(newValue, activeElement, scope.carouselIndex);
goToSlide(newIndex, {animate: false});
} else {
goToSlide(scope.carouselIndex, {animate: false});
}
}, true);
}
function swipeEnd(coords, event, forceAnimation) {
// console.log('swipeEnd', 'scope.carouselIndex', scope.carouselIndex);
// Prevent clicks on buttons inside slider to trigger "swipeEnd" event on touchend/mouseup
// console.log(iAttributes.rnCarouselOnInfiniteScroll);
if (event && !swipeMoved) {
return;
}
unbindMouseUpEvent();
pressed = false;
swipeMoved = false;
destination = startX - coords.x;
if (destination===0) {
return;
}
if (locked) {
return;
}
offset += (-destination * 100 / elWidth);
if (options.isSequential) {
var minMove = options.moveTreshold * elWidth,
absMove = -destination,
slidesMove = -Math[absMove >= 0 ? 'ceil' : 'floor'](absMove / elWidth),
shouldMove = Math.abs(absMove) > minMove;
if (currentSlides && (slidesMove + scope.carouselIndex) >= currentSlides.length) {
slidesMove = currentSlides.length - 1 - scope.carouselIndex;
}
if ((slidesMove + scope.carouselIndex) < 0) {
slidesMove = -scope.carouselIndex;
}
var moveOffset = shouldMove ? slidesMove : 0;
destination = (scope.carouselIndex + moveOffset);
goToSlide(destination);
if(iAttributes.rnCarouselOnInfiniteScrollRight!==undefined && slidesMove === 0 && scope.carouselIndex !== 0) {
$parse(iAttributes.rnCarouselOnInfiniteScrollRight)(scope)
goToSlide(0);
}
if(iAttributes.rnCarouselOnInfiniteScrollLeft!==undefined && slidesMove === 0 && scope.carouselIndex === 0 && moveOffset === 0) {
$parse(iAttributes.rnCarouselOnInfiniteScrollLeft)(scope)
goToSlide(currentSlides.length);
}
} else {
scope.$apply(function() {
scope.carouselIndex = parseInt(-offset / 100, 10);
updateBufferIndex();
});
}
}
scope.$on('$destroy', function() {
unbindMouseUpEvent();
});
scope.carouselBufferIndex = 0;
scope.carouselBufferSize = options.bufferSize;
function updateBufferIndex() {
// update and cap te buffer index
var bufferIndex = 0;
var bufferEdgeSize = (scope.carouselBufferSize - 1) / 2;
if (isBuffered) {
if (scope.carouselIndex <= bufferEdgeSize) {
// first buffer part
bufferIndex = 0;
} else if (currentSlides && currentSlides.length < scope.carouselBufferSize) {
// smaller than buffer
bufferIndex = 0;
} else if (currentSlides && scope.carouselIndex > currentSlides.length - scope.carouselBufferSize) {
// last buffer part
bufferIndex = currentSlides.length - scope.carouselBufferSize;
} else {
// compute buffer start
bufferIndex = scope.carouselIndex - bufferEdgeSize;
}
scope.carouselBufferIndex = bufferIndex;
$timeout(function() {
updateSlidesPosition(offset);
}, 0, false);
} else {
$timeout(function() {
updateSlidesPosition(offset);
}, 0, false);
}
}
function onOrientationChange() {
updateContainerWidth();
goToSlide();
}
// handle orientation change
var winEl = angular.element($window);
winEl.bind('orientationchange', onOrientationChange);
winEl.bind('resize', onOrientationChange);
scope.$on('$destroy', function() {
unbindMouseUpEvent();
winEl.unbind('orientationchange', onOrientationChange);
winEl.unbind('resize', onOrientationChange);
});
};
}
};
}
]);
})();
angular.module('angular-carousel.shifty', [])
.factory('Tweenable', function() {
/*! shifty - v1.3.4 - 2014-10-29 - http://jeremyckahn.github.io/shifty */
;(function (root) {
/*!
* Shifty Core
* By Jeremy Kahn - jeremyckahn@gmail.com
*/
var Tweenable = (function () {
'use strict';
// Aliases that get defined later in this function
var formula;
// CONSTANTS
var DEFAULT_SCHEDULE_FUNCTION;
var DEFAULT_EASING = 'linear';
var DEFAULT_DURATION = 500;
var UPDATE_TIME = 1000 / 60;
var _now = Date.now
? Date.now
: function () {return +new Date();};
var now = typeof SHIFTY_DEBUG_NOW !== 'undefined' ? SHIFTY_DEBUG_NOW : _now;
if (typeof window !== 'undefined') {
// requestAnimationFrame() shim by Paul Irish (modified for Shifty)
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
DEFAULT_SCHEDULE_FUNCTION = window.requestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.oRequestAnimationFrame
|| window.msRequestAnimationFrame
|| (window.mozCancelRequestAnimationFrame
&& window.mozRequestAnimationFrame)
|| setTimeout;
} else {
DEFAULT_SCHEDULE_FUNCTION = setTimeout;
}
function noop () {
// NOOP!
}
/*!
* Handy shortcut for doing a for-in loop. This is not a "normal" each
* function, it is optimized for Shifty. The iterator function only receives
* the property name, not the value.
* @param {Object} obj
* @param {Function(string)} fn
*/
function each (obj, fn) {
var key;
for (key in obj) {
if (Object.hasOwnProperty.call(obj, key)) {
fn(key);
}
}
}
/*!
* Perform a shallow copy of Object properties.
* @param {Object} targetObject The object to copy into
* @param {Object} srcObject The object to copy from
* @return {Object} A reference to the augmented `targetObj` Object
*/
function shallowCopy (targetObj, srcObj) {
each(srcObj, function (prop) {
targetObj[prop] = srcObj[prop];
});
return targetObj;
}
/*!
* Copies each property from src onto target, but only if the property to
* copy to target is undefined.
* @param {Object} target Missing properties in this Object are filled in
* @param {Object} src
*/
function defaults (target, src) {
each(src, function (prop) {
if (typeof target[prop] === 'undefined') {
target[prop] = src[prop];
}
});
}
/*!
* Calculates the interpolated tween values of an Object for a given
* timestamp.
* @param {Number} forPosition The position to compute the state for.
* @param {Object} currentState Current state properties.
* @param {Object} originalState: The original state properties the Object is
* tweening from.
* @param {Object} targetState: The destination state properties the Object
* is tweening to.
* @param {number} duration: The length of the tween in milliseconds.
* @param {number} timestamp: The UNIX epoch time at which the tween began.
* @param {Object} easing: This Object's keys must correspond to the keys in
* targetState.
*/
function tweenProps (forPosition, currentState, originalState, targetState,
duration, timestamp, easing) {
var normalizedPosition = (forPosition - timestamp) / duration;
var prop;
for (prop in currentState) {
if (currentState.hasOwnProperty(prop)) {
currentState[prop] = tweenProp(originalState[prop],
targetState[prop], formula[easing[prop]], normalizedPosition);
}
}
return currentState;
}
/*!
* Tweens a single property.
* @param {number} start The value that the tween started from.
* @param {number} end The value that the tween should end at.
* @param {Function} easingFunc The easing curve to apply to the tween.
* @param {number} position The normalized position (between 0.0 and 1.0) to
* calculate the midpoint of 'start' and 'end' against.
* @return {number} The tweened value.
*/
function tweenProp (start, end, easingFunc, position) {
return start + (end - start) * easingFunc(position);
}
/*!
* Applies a filter to Tweenable instance.
* @param {Tweenable} tweenable The `Tweenable` instance to call the filter
* upon.
* @param {String} filterName The name of the filter to apply.
*/
function applyFilter (tweenable, filterName) {
var filters = Tweenable.prototype.filter;
var args = tweenable._filterArgs;
each(filters, function (name) {
if (typeof filters[name][filterName] !== 'undefined') {
filters[name][filterName].apply(tweenable, args);
}
});
}
var timeoutHandler_endTime;
var timeoutHandler_currentTime;
var timeoutHandler_isEnded;
var timeoutHandler_offset;
/*!
* Handles the update logic for one step of a tween.
* @param {Tweenable} tweenable
* @param {number} timestamp
* @param {number} duration
* @param {Object} currentState
* @param {Object} originalState
* @param {Object} targetState
* @param {Object} easing
* @param {Function(Object, *, number)} step
* @param {Function(Function,number)}} schedule
*/
function timeoutHandler (tweenable, timestamp, duration, currentState,
originalState, targetState, easing, step, schedule) {
timeoutHandler_endTime = timestamp + duration;
timeoutHandler_currentTime = Math.min(now(), timeoutHandler_endTime);
timeoutHandler_isEnded =
timeoutHandler_currentTime >= timeoutHandler_endTime;
timeoutHandler_offset = duration - (
timeoutHandler_endTime - timeoutHandler_currentTime);
if (tweenable.isPlaying() && !timeoutHandler_isEnded) {
tweenable._scheduleId = schedule(tweenable._timeoutHandler, UPDATE_TIME);
applyFilter(tweenable, 'beforeTween');
tweenProps(timeoutHandler_currentTime, currentState, originalState,
targetState, duration, timestamp, easing);
applyFilter(tweenable, 'afterTween');
step(currentState, tweenable._attachment, timeoutHandler_offset);
} else if (timeoutHandler_isEnded) {
step(targetState, tweenable._attachment, timeoutHandler_offset);
tweenable.stop(true);
}
}
/*!
* Creates a usable easing Object from either a string or another easing
* Object. If `easing` is an Object, then this function clones it and fills
* in the missing properties with "linear".
* @param {Object} fromTweenParams
* @param {Object|string} easing
*/
function composeEasingObject (fromTweenParams, easing) {
var composedEasing = {};
if (typeof easing === 'string') {
each(fromTweenParams, function (prop) {
composedEasing[prop] = easing;
});
} else {
each(fromTweenParams, function (prop) {
if (!composedEasing[prop]) {
composedEasing[prop] = easing[prop] || DEFAULT_EASING;
}
});
}
return composedEasing;
}
/**
* Tweenable constructor.
* @param {Object=} opt_initialState The values that the initial tween should start at if a "from" object is not provided to Tweenable#tween.
* @param {Object=} opt_config See Tweenable.prototype.setConfig()
* @constructor
*/
function Tweenable (opt_initialState, opt_config) {
this._currentState = opt_initialState || {};
this._configured = false;
this._scheduleFunction = DEFAULT_SCHEDULE_FUNCTION;
// To prevent unnecessary calls to setConfig do not set default configuration here.
// Only set default configuration immediately before tweening if none has been set.
if (typeof opt_config !== 'undefined') {
this.setConfig(opt_config);
}
}
/**
* Configure and start a tween.
* @param {Object=} opt_config See Tweenable.prototype.setConfig()
* @return {Tweenable}
*/
Tweenable.prototype.tween = function (opt_config) {
if (this._isTweening) {
return this;
}
// Only set default config if no configuration has been set previously and none is provided now.
if (opt_config !== undefined || !this._configured) {
this.setConfig(opt_config);
}
this._timestamp = now();
this._start(this.get(), this._attachment);
return this.resume();
};
/**
* Sets the tween configuration. `config` may have the following options:
*
* - __from__ (_Object=_): Starting position. If omitted, the current state is used.
* - __to__ (_Object=_): Ending position.
* - __duration__ (_number=_): How many milliseconds to animate for.
* - __start__ (_Function(Object)_): Function to execute when the tween begins. Receives the state of the tween as the first parameter. Attachment is the second parameter.
* - __step__ (_Function(Object, *, number)_): Function to execute on every tick. Receives the state of the tween as the first parameter. Attachment is the second parameter, and the time elapsed since the start of the tween is the third parameter. This function is not called on the final step of the animation, but `finish` is.
* - __finish__ (_Function(Object, *)_): Function to execute upon tween completion. Receives the state of the tween as the first parameter. Attachment is the second parameter.
* - __easing__ (_Object|string=_): Easing curve name(s) to use for the tween.
* - __attachment__ (_Object|string|any=_): Value that is attached to this instance and passed on to the step/start/finish methods.
* @param {Object} config
* @return {Tweenable}
*/
Tweenable.prototype.setConfig = function (config) {
config = config || {};
this._configured = true;
// Attach something to this Tweenable instance (e.g.: a DOM element, an object, a string, etc.);
this._attachment = config.attachment;
// Init the internal state
this._pausedAtTime = null;
this._scheduleId = null;
this._start = config.start || noop;
this._step = config.step || noop;
this._finish = config.finish || noop;
this._duration = config.duration || DEFAULT_DURATION;
this._currentState = config.from || this.get();
this._originalState = this.get();
this._targetState = config.to || this.get();
// Aliases used below
var currentState = this._currentState;
var targetState = this._targetState;
// Ensure that there is always something to tween to.
defaults(targetState, currentState);
this._easing = composeEasingObject(
currentState, config.easing || DEFAULT_EASING);
this._filterArgs =
[currentState, this._originalState, targetState, this._easing];
applyFilter(this, 'tweenCreated');
return this;
};
/**
* Gets the current state.
* @return {Object}
*/
Tweenable.prototype.get = function () {
return shallowCopy({}, this._currentState);
};
/**
* Sets the current state.
* @param {Object} state
*/
Tweenable.prototype.set = function (state) {
this._currentState = state;
};
/**
* Pauses a tween. Paused tweens can be resumed from the point at which they were paused. This is different than [`stop()`](#stop), as that method causes a tween to start over when it is resumed.
* @return {Tweenable}
*/
Tweenable.prototype.pause = function () {
this._pausedAtTime = now();
this._isPaused = true;
return this;
};
/**
* Resumes a paused tween.
* @return {Tweenable}
*/
Tweenable.prototype.resume = function () {
if (this._isPaused) {
this._timestamp += now() - this._pausedAtTime;
}
this._isPaused = false;
this._isTweening = true;
var self = this;
this._timeoutHandler = function () {
timeoutHandler(self, self._timestamp, self._duration, self._currentState,
self._originalState, self._targetState, self._easing, self._step,
self._scheduleFunction);
};
this._timeoutHandler();
return this;
};
/**
* Move the state of the animation to a specific point in the tween's timeline.
* If the animation is not running, this will cause the `step` handlers to be
* called.
* @param {millisecond} millisecond The millisecond of the animation to seek to.
* @return {Tweenable}
*/
Tweenable.prototype.seek = function (millisecond) {
this._timestamp = now() - millisecond;
if (!this.isPlaying()) {
this._isTweening = true;
this._isPaused = false;
// If the animation is not running, call timeoutHandler to make sure that
// any step handlers are run.
timeoutHandler(this, this._timestamp, this._duration, this._currentState,
this._originalState, this._targetState, this._easing, this._step,
this._scheduleFunction);
this._timeoutHandler();
this.pause();
}
return this;
};
/**
* Stops and cancels a tween.
* @param {boolean=} gotoEnd If false or omitted, the tween just stops at its current state, and the "finish" handler is not invoked. If true, the tweened object's values are instantly set to the target values, and "finish" is invoked.
* @return {Tweenable}
*/
Tweenable.prototype.stop = function (gotoEnd) {
this._isTweening = false;
this._isPaused = false;
this._timeoutHandler = noop;
(root.cancelAnimationFrame ||
root.webkitCancelAnimationFrame ||
root.oCancelAnimationFrame ||
root.msCancelAnimationFrame ||
root.mozCancelRequestAnimationFrame ||
root.clearTimeout)(this._scheduleId);
if (gotoEnd) {
shallowCopy(this._currentState, this._targetState);
applyFilter(this, 'afterTweenEnd');
this._finish.call(this, this._currentState, this._attachment);
}
return this;
};
/**
* Returns whether or not a tween is running.
* @return {boolean}
*/
Tweenable.prototype.isPlaying = function () {
return this._isTweening && !this._isPaused;
};
/**
* Sets a custom schedule function.
*
* If a custom function is not set the default one is used [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame) if available, otherwise [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/Window.setTimeout)).
*
* @param {Function(Function,number)} scheduleFunction The function to be called to schedule the next frame to be rendered
*/
Tweenable.prototype.setScheduleFunction = function (scheduleFunction) {
this._scheduleFunction = scheduleFunction;
};
/**
* `delete`s all "own" properties. Call this when the `Tweenable` instance is no longer needed to free memory.
*/
Tweenable.prototype.dispose = function () {
var prop;
for (prop in this) {
if (this.hasOwnProperty(prop)) {
delete this[prop];
}
}
};
/*!
* Filters are used for transforming the properties of a tween at various
* points in a Tweenable's life cycle. See the README for more info on this.
*/
Tweenable.prototype.filter = {};
/*!
* This object contains all of the tweens available to Shifty. It is extendible - simply attach properties to the Tweenable.prototype.formula Object following the same format at linear.
*
* `pos` should be a normalized `number` (between 0 and 1).
*/
Tweenable.prototype.formula = {
linear: function (pos) {
return pos;
}
};
formula = Tweenable.prototype.formula;
shallowCopy(Tweenable, {
'now': now
,'each': each
,'tweenProps': tweenProps
,'tweenProp': tweenProp
,'applyFilter': applyFilter
,'shallowCopy': shallowCopy
,'defaults': defaults
,'composeEasingObject': composeEasingObject
});
root.Tweenable = Tweenable;
return Tweenable;
} ());
/*!
* All equations are adapted from Thomas Fuchs' [Scripty2](https://github.com/madrobby/scripty2/blob/master/src/effects/transitions/penner.js).
*
* Based on Easing Equations (c) 2003 [Robert Penner](http://www.robertpenner.com/), all rights reserved. This work is [subject to terms](http://www.robertpenner.com/easing_terms_of_use.html).
*/
/*!
* TERMS OF USE - EASING EQUATIONS
* Open source under the BSD License.
* Easing Equations (c) 2003 Robert Penner, all rights reserved.
*/
;(function () {
Tweenable.shallowCopy(Tweenable.prototype.formula, {
easeInQuad: function (pos) {
return Math.pow(pos, 2);
},
easeOutQuad: function (pos) {
return -(Math.pow((pos - 1), 2) - 1);
},
easeInOutQuad: function (pos) {
if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(pos,2);}
return -0.5 * ((pos -= 2) * pos - 2);
},
easeInCubic: function (pos) {
return Math.pow(pos, 3);
},
easeOutCubic: function (pos) {
return (Math.pow((pos - 1), 3) + 1);
},
easeInOutCubic: function (pos) {
if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(pos,3);}
return 0.5 * (Math.pow((pos - 2),3) + 2);
},
easeInQuart: function (pos) {
return Math.pow(pos, 4);
},
easeOutQuart: function (pos) {
return -(Math.pow((pos - 1), 4) - 1);
},
easeInOutQuart: function (pos) {
if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(pos,4);}
return -0.5 * ((pos -= 2) * Math.pow(pos,3) - 2);
},
easeInQuint: function (pos) {
return Math.pow(pos, 5);
},
easeOutQuint: function (pos) {
return (Math.pow((pos - 1), 5) + 1);
},
easeInOutQuint: function (pos) {
if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(pos,5);}
return 0.5 * (Math.pow((pos - 2),5) + 2);
},
easeInSine: function (pos) {
return -Math.cos(pos * (Math.PI / 2)) + 1;
},
easeOutSine: function (pos) {
return Math.sin(pos * (Math.PI / 2));
},
easeInOutSine: function (pos) {
return (-0.5 * (Math.cos(Math.PI * pos) - 1));
},
easeInExpo: function (pos) {
return (pos === 0) ? 0 : Math.pow(2, 10 * (pos - 1));
},
easeOutExpo: function (pos) {
return (pos === 1) ? 1 : -Math.pow(2, -10 * pos) + 1;
},
easeInOutExpo: function (pos) {
if (pos === 0) {return 0;}
if (pos === 1) {return 1;}
if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(2,10 * (pos - 1));}
return 0.5 * (-Math.pow(2, -10 * --pos) + 2);
},
easeInCirc: function (pos) {
return -(Math.sqrt(1 - (pos * pos)) - 1);
},
easeOutCirc: function (pos) {
return Math.sqrt(1 - Math.pow((pos - 1), 2));
},
easeInOutCirc: function (pos) {
if ((pos /= 0.5) < 1) {return -0.5 * (Math.sqrt(1 - pos * pos) - 1);}
return 0.5 * (Math.sqrt(1 - (pos -= 2) * pos) + 1);
},
easeOutBounce: function (pos) {
if ((pos) < (1 / 2.75)) {
return (7.5625 * pos * pos);
} else if (pos < (2 / 2.75)) {
return (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75);
} else if (pos < (2.5 / 2.75)) {
return (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375);
} else {
return (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375);
}
},
easeInBack: function (pos) {
var s = 1.70158;
return (pos) * pos * ((s + 1) * pos - s);
},
easeOutBack: function (pos) {
var s = 1.70158;
return (pos = pos - 1) * pos * ((s + 1) * pos + s) + 1;
},
easeInOutBack: function (pos) {
var s = 1.70158;
if ((pos /= 0.5) < 1) {return 0.5 * (pos * pos * (((s *= (1.525)) + 1) * pos - s));}
return 0.5 * ((pos -= 2) * pos * (((s *= (1.525)) + 1) * pos + s) + 2);
},
elastic: function (pos) {
return -1 * Math.pow(4,-8 * pos) * Math.sin((pos * 6 - 1) * (2 * Math.PI) / 2) + 1;
},
swingFromTo: function (pos) {
var s = 1.70158;
return ((pos /= 0.5) < 1) ? 0.5 * (pos * pos * (((s *= (1.525)) + 1) * pos - s)) :
0.5 * ((pos -= 2) * pos * (((s *= (1.525)) + 1) * pos + s) + 2);
},
swingFrom: function (pos) {
var s = 1.70158;
return pos * pos * ((s + 1) * pos - s);
},
swingTo: function (pos) {
var s = 1.70158;
return (pos -= 1) * pos * ((s + 1) * pos + s) + 1;
},
bounce: function (pos) {
if (pos < (1 / 2.75)) {
return (7.5625 * pos * pos);
} else if (pos < (2 / 2.75)) {
return (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75);
} else if (pos < (2.5 / 2.75)) {
return (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375);
} else {
return (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375);
}
},
bouncePast: function (pos) {
if (pos < (1 / 2.75)) {
return (7.5625 * pos * pos);
} else if (pos < (2 / 2.75)) {
return 2 - (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75);
} else if (pos < (2.5 / 2.75)) {
return 2 - (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375);
} else {
return 2 - (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375);
}
},
easeFromTo: function (pos) {
if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(pos,4);}
return -0.5 * ((pos -= 2) * Math.pow(pos,3) - 2);
},
easeFrom: function (pos) {
return Math.pow(pos,4);
},
easeTo: function (pos) {
return Math.pow(pos,0.25);
}
});
}());
/*!
* The Bezier magic in this file is adapted/copied almost wholesale from
* [Scripty2](https://github.com/madrobby/scripty2/blob/master/src/effects/transitions/cubic-bezier.js),
* which was adapted from Apple code (which probably came from
* [here](http://opensource.apple.com/source/WebCore/WebCore-955.66/platform/graphics/UnitBezier.h)).
* Special thanks to Apple and Thomas Fuchs for much of this code.
*/
/*!
* Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder(s) nor the names of any
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
;(function () {
// port of webkit cubic bezier handling by http://www.netzgesta.de/dev/
function cubicBezierAtTime(t,p1x,p1y,p2x,p2y,duration) {
var ax = 0,bx = 0,cx = 0,ay = 0,by = 0,cy = 0;
function sampleCurveX(t) {return ((ax * t + bx) * t + cx) * t;}
function sampleCurveY(t) {return ((ay * t + by) * t + cy) * t;}
function sampleCurveDerivativeX(t) {return (3.0 * ax * t + 2.0 * bx) * t + cx;}
function solveEpsilon(duration) {return 1.0 / (200.0 * duration);}
function solve(x,epsilon) {return sampleCurveY(solveCurveX(x,epsilon));}
function fabs(n) {if (n >= 0) {return n;}else {return 0 - n;}}
function solveCurveX(x,epsilon) {
var t0,t1,t2,x2,d2,i;
for (t2 = x, i = 0; i < 8; i++) {x2 = sampleCurveX(t2) - x; if (fabs(x2) < epsilon) {return t2;} d2 = sampleCurveDerivativeX(t2); if (fabs(d2) < 1e-6) {break;} t2 = t2 - x2 / d2;}
t0 = 0.0; t1 = 1.0; t2 = x; if (t2 < t0) {return t0;} if (t2 > t1) {return t1;}
while (t0 < t1) {x2 = sampleCurveX(t2); if (fabs(x2 - x) < epsilon) {return t2;} if (x > x2) {t0 = t2;}else {t1 = t2;} t2 = (t1 - t0) * 0.5 + t0;}
return t2; // Failure.
}
cx = 3.0 * p1x; bx = 3.0 * (p2x - p1x) - cx; ax = 1.0 - cx - bx; cy = 3.0 * p1y; by = 3.0 * (p2y - p1y) - cy; ay = 1.0 - cy - by;
return solve(t, solveEpsilon(duration));
}
/*!
* getCubicBezierTransition(x1, y1, x2, y2) -> Function
*
* Generates a transition easing function that is compatible
* with WebKit's CSS transitions `-webkit-transition-timing-function`
* CSS property.
*
* The W3C has more information about
*
* CSS3 transition timing functions .
*
* @param {number} x1
* @param {number} y1
* @param {number} x2
* @param {number} y2
* @return {function}
*/
function getCubicBezierTransition (x1, y1, x2, y2) {
return function (pos) {
return cubicBezierAtTime(pos,x1,y1,x2,y2,1);
};
}
// End ported code
/**
* Creates a Bezier easing function and attaches it to `Tweenable.prototype.formula`. This function gives you total control over the easing curve. Matthew Lein's [Ceaser](http://matthewlein.com/ceaser/) is a useful tool for visualizing the curves you can make with this function.
*
* @param {string} name The name of the easing curve. Overwrites the old easing function on Tweenable.prototype.formula if it exists.
* @param {number} x1
* @param {number} y1
* @param {number} x2
* @param {number} y2
* @return {function} The easing function that was attached to Tweenable.prototype.formula.
*/
Tweenable.setBezierFunction = function (name, x1, y1, x2, y2) {
var cubicBezierTransition = getCubicBezierTransition(x1, y1, x2, y2);
cubicBezierTransition.x1 = x1;
cubicBezierTransition.y1 = y1;
cubicBezierTransition.x2 = x2;
cubicBezierTransition.y2 = y2;
return Tweenable.prototype.formula[name] = cubicBezierTransition;
};
/**
* `delete`s an easing function from `Tweenable.prototype.formula`. Be careful with this method, as it `delete`s whatever easing formula matches `name` (which means you can delete default Shifty easing functions).
*
* @param {string} name The name of the easing function to delete.
* @return {function}
*/
Tweenable.unsetBezierFunction = function (name) {
delete Tweenable.prototype.formula[name];
};
})();
;(function () {
function getInterpolatedValues (
from, current, targetState, position, easing) {
return Tweenable.tweenProps(
position, current, from, targetState, 1, 0, easing);
}
// Fake a Tweenable and patch some internals. This approach allows us to
// skip uneccessary processing and object recreation, cutting down on garbage
// collection pauses.
var mockTweenable = new Tweenable();
mockTweenable._filterArgs = [];
/**
* Compute the midpoint of two Objects. This method effectively calculates a specific frame of animation that [Tweenable#tween](shifty.core.js.html#tween) does many times over the course of a tween.
*
* Example:
*
* var interpolatedValues = Tweenable.interpolate({
* width: '100px',
* opacity: 0,
* color: '#fff'
* }, {
* width: '200px',
* opacity: 1,
* color: '#000'
* }, 0.5);
*
* console.log(interpolatedValues);
* // {opacity: 0.5, width: "150px", color: "rgb(127,127,127)"}
*
* @param {Object} from The starting values to tween from.
* @param {Object} targetState The ending values to tween to.
* @param {number} position The normalized position value (between 0.0 and 1.0) to interpolate the values between `from` and `to` for. `from` represents 0 and `to` represents `1`.
* @param {string|Object} easing The easing curve(s) to calculate the midpoint against. You can reference any easing function attached to `Tweenable.prototype.formula`. If omitted, this defaults to "linear".
* @return {Object}
*/
Tweenable.interpolate = function (from, targetState, position, easing) {
var current = Tweenable.shallowCopy({}, from);
var easingObject = Tweenable.composeEasingObject(
from, easing || 'linear');
mockTweenable.set({});
// Alias and reuse the _filterArgs array instead of recreating it.
var filterArgs = mockTweenable._filterArgs;
filterArgs.length = 0;
filterArgs[0] = current;
filterArgs[1] = from;
filterArgs[2] = targetState;
filterArgs[3] = easingObject;
// Any defined value transformation must be applied
Tweenable.applyFilter(mockTweenable, 'tweenCreated');
Tweenable.applyFilter(mockTweenable, 'beforeTween');
var interpolatedValues = getInterpolatedValues(
from, current, targetState, position, easingObject);
// Transform values back into their original format
Tweenable.applyFilter(mockTweenable, 'afterTween');
return interpolatedValues;
};
}());
/**
* Adds string interpolation support to Shifty.
*
* The Token extension allows Shifty to tween numbers inside of strings. Among
* other things, this allows you to animate CSS properties. For example, you
* can do this:
*
* var tweenable = new Tweenable();
* tweenable.tween({
* from: { transform: 'translateX(45px)'},
* to: { transform: 'translateX(90xp)'}
* });
*
* ` `
* `translateX(45)` will be tweened to `translateX(90)`. To demonstrate:
*
* var tweenable = new Tweenable();
* tweenable.tween({
* from: { transform: 'translateX(45px)'},
* to: { transform: 'translateX(90px)'},
* step: function (state) {
* console.log(state.transform);
* }
* });
*
* ` `
* The above snippet will log something like this in the console:
*
* translateX(60.3px)
* ...
* translateX(76.05px)
* ...
* translateX(90px)
*
* ` `
* Another use for this is animating colors:
*
* var tweenable = new Tweenable();
* tweenable.tween({
* from: { color: 'rgb(0,255,0)'},
* to: { color: 'rgb(255,0,255)'},
* step: function (state) {
* console.log(state.color);
* }
* });
*
* ` `
* The above snippet will log something like this:
*
* rgb(84,170,84)
* ...
* rgb(170,84,170)
* ...
* rgb(255,0,255)
*
* ` `
* This extension also supports hexadecimal colors, in both long (`#ff00ff`)
* and short (`#f0f`) forms. Be aware that hexadecimal input values will be
* converted into the equivalent RGB output values. This is done to optimize
* for performance.
*
* var tweenable = new Tweenable();
* tweenable.tween({
* from: { color: '#0f0'},
* to: { color: '#f0f'},
* step: function (state) {
* console.log(state.color);
* }
* });
*
* ` `
* This snippet will generate the same output as the one before it because
* equivalent values were supplied (just in hexadecimal form rather than RGB):
*
* rgb(84,170,84)
* ...
* rgb(170,84,170)
* ...
* rgb(255,0,255)
*
* ` `
* ` `
* ## Easing support
*
* Easing works somewhat differently in the Token extension. This is because
* some CSS properties have multiple values in them, and you might need to
* tween each value along its own easing curve. A basic example:
*
* var tweenable = new Tweenable();
* tweenable.tween({
* from: { transform: 'translateX(0px) translateY(0px)'},
* to: { transform: 'translateX(100px) translateY(100px)'},
* easing: { transform: 'easeInQuad' },
* step: function (state) {
* console.log(state.transform);
* }
* });
*
* ` `
* The above snippet create values like this:
*
* translateX(11.560000000000002px) translateY(11.560000000000002px)
* ...
* translateX(46.24000000000001px) translateY(46.24000000000001px)
* ...
* translateX(100px) translateY(100px)
*
* ` `
* In this case, the values for `translateX` and `translateY` are always the
* same for each step of the tween, because they have the same start and end
* points and both use the same easing curve. We can also tween `translateX`
* and `translateY` along independent curves:
*
* var tweenable = new Tweenable();
* tweenable.tween({
* from: { transform: 'translateX(0px) translateY(0px)'},
* to: { transform: 'translateX(100px) translateY(100px)'},
* easing: { transform: 'easeInQuad bounce' },
* step: function (state) {
* console.log(state.transform);
* }
* });
*
* ` `
* The above snippet create values like this:
*
* translateX(10.89px) translateY(82.355625px)
* ...
* translateX(44.89000000000001px) translateY(86.73062500000002px)
* ...
* translateX(100px) translateY(100px)
*
* ` `
* `translateX` and `translateY` are not in sync anymore, because `easeInQuad`
* was specified for `translateX` and `bounce` for `translateY`. Mixing and
* matching easing curves can make for some interesting motion in your
* animations.
*
* The order of the space-separated easing curves correspond the token values
* they apply to. If there are more token values than easing curves listed,
* the last easing curve listed is used.
*/
function token () {
// Functionality for this extension runs implicitly if it is loaded.
} /*!*/
// token function is defined above only so that dox-foundation sees it as
// documentation and renders it. It is never used, and is optimized away at
// build time.
;(function (Tweenable) {
/*!
* @typedef {{
* formatString: string
* chunkNames: Array.
* }}
*/
var formatManifest;
// CONSTANTS
var R_NUMBER_COMPONENT = /(\d|\-|\.)/;
var R_FORMAT_CHUNKS = /([^\-0-9\.]+)/g;
var R_UNFORMATTED_VALUES = /[0-9.\-]+/g;
var R_RGB = new RegExp(
'rgb\\(' + R_UNFORMATTED_VALUES.source +
(/,\s*/.source) + R_UNFORMATTED_VALUES.source +
(/,\s*/.source) + R_UNFORMATTED_VALUES.source + '\\)', 'g');
var R_RGB_PREFIX = /^.*\(/;
var R_HEX = /#([0-9]|[a-f]){3,6}/gi;
var VALUE_PLACEHOLDER = 'VAL';
// HELPERS
var getFormatChunksFrom_accumulator = [];
/*!
* @param {Array.number} rawValues
* @param {string} prefix
*
* @return {Array.}
*/
function getFormatChunksFrom (rawValues, prefix) {
getFormatChunksFrom_accumulator.length = 0;
var rawValuesLength = rawValues.length;
var i;
for (i = 0; i < rawValuesLength; i++) {
getFormatChunksFrom_accumulator.push('_' + prefix + '_' + i);
}
return getFormatChunksFrom_accumulator;
}
/*!
* @param {string} formattedString
*
* @return {string}
*/
function getFormatStringFrom (formattedString) {
var chunks = formattedString.match(R_FORMAT_CHUNKS);
if (!chunks) {
// chunks will be null if there were no tokens to parse in
// formattedString (for example, if formattedString is '2'). Coerce
// chunks to be useful here.
chunks = ['', ''];
// If there is only one chunk, assume that the string is a number
// followed by a token...
// NOTE: This may be an unwise assumption.
} else if (chunks.length === 1 ||
// ...or if the string starts with a number component (".", "-", or a
// digit)...
formattedString[0].match(R_NUMBER_COMPONENT)) {
// ...prepend an empty string here to make sure that the formatted number
// is properly replaced by VALUE_PLACEHOLDER
chunks.unshift('');
}
return chunks.join(VALUE_PLACEHOLDER);
}
/*!
* Convert all hex color values within a string to an rgb string.
*
* @param {Object} stateObject
*
* @return {Object} The modified obj
*/
function sanitizeObjectForHexProps (stateObject) {
Tweenable.each(stateObject, function (prop) {
var currentProp = stateObject[prop];
if (typeof currentProp === 'string' && currentProp.match(R_HEX)) {
stateObject[prop] = sanitizeHexChunksToRGB(currentProp);
}
});
}
/*!
* @param {string} str
*
* @return {string}
*/
function sanitizeHexChunksToRGB (str) {
return filterStringChunks(R_HEX, str, convertHexToRGB);
}
/*!
* @param {string} hexString
*
* @return {string}
*/
function convertHexToRGB (hexString) {
var rgbArr = hexToRGBArray(hexString);
return 'rgb(' + rgbArr[0] + ',' + rgbArr[1] + ',' + rgbArr[2] + ')';
}
var hexToRGBArray_returnArray = [];
/*!
* Convert a hexadecimal string to an array with three items, one each for
* the red, blue, and green decimal values.
*
* @param {string} hex A hexadecimal string.
*
* @returns {Array.} The converted Array of RGB values if `hex` is a
* valid string, or an Array of three 0's.
*/
function hexToRGBArray (hex) {
hex = hex.replace(/#/, '');
// If the string is a shorthand three digit hex notation, normalize it to
// the standard six digit notation
if (hex.length === 3) {
hex = hex.split('');
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
hexToRGBArray_returnArray[0] = hexToDec(hex.substr(0, 2));
hexToRGBArray_returnArray[1] = hexToDec(hex.substr(2, 2));
hexToRGBArray_returnArray[2] = hexToDec(hex.substr(4, 2));
return hexToRGBArray_returnArray;
}
/*!
* Convert a base-16 number to base-10.
*
* @param {Number|String} hex The value to convert
*
* @returns {Number} The base-10 equivalent of `hex`.
*/
function hexToDec (hex) {
return parseInt(hex, 16);
}
/*!
* Runs a filter operation on all chunks of a string that match a RegExp
*
* @param {RegExp} pattern
* @param {string} unfilteredString
* @param {function(string)} filter
*
* @return {string}
*/
function filterStringChunks (pattern, unfilteredString, filter) {
var pattenMatches = unfilteredString.match(pattern);
var filteredString = unfilteredString.replace(pattern, VALUE_PLACEHOLDER);
if (pattenMatches) {
var pattenMatchesLength = pattenMatches.length;
var currentChunk;
for (var i = 0; i < pattenMatchesLength; i++) {
currentChunk = pattenMatches.shift();
filteredString = filteredString.replace(
VALUE_PLACEHOLDER, filter(currentChunk));
}
}
return filteredString;
}
/*!
* Check for floating point values within rgb strings and rounds them.
*
* @param {string} formattedString
*
* @return {string}
*/
function sanitizeRGBChunks (formattedString) {
return filterStringChunks(R_RGB, formattedString, sanitizeRGBChunk);
}
/*!
* @param {string} rgbChunk
*
* @return {string}
*/
function sanitizeRGBChunk (rgbChunk) {
var numbers = rgbChunk.match(R_UNFORMATTED_VALUES);
var numbersLength = numbers.length;
var sanitizedString = rgbChunk.match(R_RGB_PREFIX)[0];
for (var i = 0; i < numbersLength; i++) {
sanitizedString += parseInt(numbers[i], 10) + ',';
}
sanitizedString = sanitizedString.slice(0, -1) + ')';
return sanitizedString;
}
/*!
* @param {Object} stateObject
*
* @return {Object} An Object of formatManifests that correspond to
* the string properties of stateObject
*/
function getFormatManifests (stateObject) {
var manifestAccumulator = {};
Tweenable.each(stateObject, function (prop) {
var currentProp = stateObject[prop];
if (typeof currentProp === 'string') {
var rawValues = getValuesFrom(currentProp);
manifestAccumulator[prop] = {
'formatString': getFormatStringFrom(currentProp)
,'chunkNames': getFormatChunksFrom(rawValues, prop)
};
}
});
return manifestAccumulator;
}
/*!
* @param {Object} stateObject
* @param {Object} formatManifests
*/
function expandFormattedProperties (stateObject, formatManifests) {
Tweenable.each(formatManifests, function (prop) {
var currentProp = stateObject[prop];
var rawValues = getValuesFrom(currentProp);
var rawValuesLength = rawValues.length;
for (var i = 0; i < rawValuesLength; i++) {
stateObject[formatManifests[prop].chunkNames[i]] = +rawValues[i];
}
delete stateObject[prop];
});
}
/*!
* @param {Object} stateObject
* @param {Object} formatManifests
*/
function collapseFormattedProperties (stateObject, formatManifests) {
Tweenable.each(formatManifests, function (prop) {
var currentProp = stateObject[prop];
var formatChunks = extractPropertyChunks(
stateObject, formatManifests[prop].chunkNames);
var valuesList = getValuesList(
formatChunks, formatManifests[prop].chunkNames);
currentProp = getFormattedValues(
formatManifests[prop].formatString, valuesList);
stateObject[prop] = sanitizeRGBChunks(currentProp);
});
}
/*!
* @param {Object} stateObject
* @param {Array.} chunkNames
*
* @return {Object} The extracted value chunks.
*/
function extractPropertyChunks (stateObject, chunkNames) {
var extractedValues = {};
var currentChunkName, chunkNamesLength = chunkNames.length;
for (var i = 0; i < chunkNamesLength; i++) {
currentChunkName = chunkNames[i];
extractedValues[currentChunkName] = stateObject[currentChunkName];
delete stateObject[currentChunkName];
}
return extractedValues;
}
var getValuesList_accumulator = [];
/*!
* @param {Object} stateObject
* @param {Array.} chunkNames
*
* @return {Array.}
*/
function getValuesList (stateObject, chunkNames) {
getValuesList_accumulator.length = 0;
var chunkNamesLength = chunkNames.length;
for (var i = 0; i < chunkNamesLength; i++) {
getValuesList_accumulator.push(stateObject[chunkNames[i]]);
}
return getValuesList_accumulator;
}
/*!
* @param {string} formatString
* @param {Array.} rawValues
*
* @return {string}
*/
function getFormattedValues (formatString, rawValues) {
var formattedValueString = formatString;
var rawValuesLength = rawValues.length;
for (var i = 0; i < rawValuesLength; i++) {
formattedValueString = formattedValueString.replace(
VALUE_PLACEHOLDER, +rawValues[i].toFixed(4));
}
return formattedValueString;
}
/*!
* Note: It's the duty of the caller to convert the Array elements of the
* return value into numbers. This is a performance optimization.
*
* @param {string} formattedString
*
* @return {Array.|null}
*/
function getValuesFrom (formattedString) {
return formattedString.match(R_UNFORMATTED_VALUES);
}
/*!
* @param {Object} easingObject
* @param {Object} tokenData
*/
function expandEasingObject (easingObject, tokenData) {
Tweenable.each(tokenData, function (prop) {
var currentProp = tokenData[prop];
var chunkNames = currentProp.chunkNames;
var chunkLength = chunkNames.length;
var easingChunks = easingObject[prop].split(' ');
var lastEasingChunk = easingChunks[easingChunks.length - 1];
for (var i = 0; i < chunkLength; i++) {
easingObject[chunkNames[i]] = easingChunks[i] || lastEasingChunk;
}
delete easingObject[prop];
});
}
/*!
* @param {Object} easingObject
* @param {Object} tokenData
*/
function collapseEasingObject (easingObject, tokenData) {
Tweenable.each(tokenData, function (prop) {
var currentProp = tokenData[prop];
var chunkNames = currentProp.chunkNames;
var chunkLength = chunkNames.length;
var composedEasingString = '';
for (var i = 0; i < chunkLength; i++) {
composedEasingString += ' ' + easingObject[chunkNames[i]];
delete easingObject[chunkNames[i]];
}
easingObject[prop] = composedEasingString.substr(1);
});
}
Tweenable.prototype.filter.token = {
'tweenCreated': function (currentState, fromState, toState, easingObject) {
sanitizeObjectForHexProps(currentState);
sanitizeObjectForHexProps(fromState);
sanitizeObjectForHexProps(toState);
this._tokenData = getFormatManifests(currentState);
},
'beforeTween': function (currentState, fromState, toState, easingObject) {
expandEasingObject(easingObject, this._tokenData);
expandFormattedProperties(currentState, this._tokenData);
expandFormattedProperties(fromState, this._tokenData);
expandFormattedProperties(toState, this._tokenData);
},
'afterTween': function (currentState, fromState, toState, easingObject) {
collapseFormattedProperties(currentState, this._tokenData);
collapseFormattedProperties(fromState, this._tokenData);
collapseFormattedProperties(toState, this._tokenData);
collapseEasingObject(easingObject, this._tokenData);
}
};
} (Tweenable));
}(window));
return window.Tweenable;
});
(function() {
"use strict";
angular.module('angular-carousel')
.filter('carouselSlice', function() {
return function(collection, start, size) {
if (angular.isArray(collection)) {
return collection.slice(start, start + size);
} else if (angular.isObject(collection)) {
// dont try to slice collections :)
return collection;
}
};
});
})();
(function () {
'use strict';
var ngAntiForgeryService = angular.module('ngAntiForgeryService', ['ngResource']);
ngAntiForgeryService.service('AntiForgery', ['$resource', function ($resource) {
this.getAntiForgery = function (prefix) {
// Initiates the AJAX call
var req = $.ajax("/acs-refresh-forgery-token") ,
chained = req.then( function(html) {
return $('
').html(html).find('input[type="hidden"]').val();
});
return chained;
}
}]);
})();
(function () {
'use strict';
var ngChartsService = angular.module('ngChartsService', ['ngResource']);
ngChartsService.service('Charts', ['$resource', '$http', function ($resource) {
this.getClientChartData = function (url, dataaux, prefix) {
return $resource(prefix + '/webapi/clientdashboard/getchartdata?chartName=' + url, {},
{
query: {
method: 'POST',
params: {
data: dataaux
}, isArray: false
}
}).query().$promise;
};
this.getInternalChartData = function (url, dataaux, prefix) {
return $resource(prefix + '/webapi/internaldashboard/getchartdata?chartName=' + url, {},
{
query: {
method: 'POST',
params: {
data: dataaux
}, isArray: false
}
}).query().$promise;
};
this.drawLineDoubleChart = function (labels, values, div) {
var table = [];
var aux = ['void'];
aux = aux.concat(labels);
table.push(aux);
for (var i = 0; i < values.length; i++) {
var aux1 = [];
aux1.push(values[i].label);
aux1 = aux1.concat(values[i].data)
table.push(aux1);
}
var rows = this.transpose(table);
var data = google.visualization.arrayToDataTable(
rows
);
var columns = [];
var series = {};
for (var i = 0; i < data.getNumberOfColumns(); i++) {
columns.push(i);
if (i > 0) {
series[i - 1] = {};
}
}
var options = {
legend: { position: 'top' },
//chartArea: { 'width': '85%', 'height': '80%' },
series: {
0: { targetAxisIndex: 0 },
1: { targetAxisIndex: 1 },
2: { targetAxisIndex: 0 },
3: { targetAxisIndex: 1 }
},
vAxes: {
0: {
},
1: {
},
},
};
var chart = new google.visualization.LineChart(
document.getElementById(div));
chart.draw(data, options);
google.visualization.events.addListener(chart, 'select', function () {
var sel = chart.getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (typeof sel[0].row === 'undefined'
|| sel[0].row == null) {
var col = sel[0].column;
if (columns[col] == col) {
// hide the data series
columns[col] = {
label: data.getColumnLabel(col),
type: data.getColumnType(col),
calc: function () {
return null;
}
};
// grey out the legend entry
series[col - 1].color = '#CCCCCC';
}
else {
// show the data series
columns[col] = col;
series[col - 1].color = null;
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
}
});
}
this.drawGauges = function (data, div) {
var dat = google.visualization.arrayToDataTable(data
);
var options = {
width: 400, height: 120,
redFrom: 90, redTo: 100,
yellowFrom: 75, yellowTo: 90,
minorTicks: 5
};
var chart = new google.visualization.Gauge(document.getElementById(div));
chart.draw(dat, options);
}
this.drawLineSimpleChart = function (labels, values, div) {
var table = [];
var aux = ['void'];
aux = aux.concat(labels);
table.push(aux);
for (var i = 0; i < values.length; i++) {
var aux1 = [];
aux1.push(values[i].label);
aux1 = aux1.concat(values[i].data)
table.push(aux1);
}
var rows = this.transpose(table);
var data = google.visualization.arrayToDataTable(
rows
);
var columns = [];
var series = {};
for (var i = 0; i < data.getNumberOfColumns(); i++) {
columns.push(i);
if (i > 0) {
series[i - 1] = {};
}
}
var options = {
legend: { position: 'top' },
//chartArea: { 'width': '85%', 'height': '80%' },
series: {
0: { targetAxisIndex: 0 },
1: { targetAxisIndex: 1 }
},
vAxes: {
0: {
},
1: {
},
},
};
var chart = new google.visualization.LineChart(
document.getElementById(div));
chart.draw(data, options);
google.visualization.events.addListener(chart, 'select', function () {
var sel = chart.getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (typeof sel[0].row === 'undefined'
|| sel[0].row == null) {
var col = sel[0].column;
if (columns[col] == col) {
// hide the data series
columns[col] = {
label: data.getColumnLabel(col),
type: data.getColumnType(col),
calc: function () {
return null;
}
};
// grey out the legend entry
series[col - 1].color = '#CCCCCC';
}
else {
// show the data series
columns[col] = col;
series[col - 1].color = null;
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
}
});
};
this.drawLineSimpleChartNoAxis = function (labels, values, div, title) {
var table = [];
var aux = ['void'];
aux = aux.concat(labels);
table.push(aux);
for (var i = 0; i < values.length; i++) {
var aux1 = [];
aux1.push(values[i].label.toLowerCase());
aux1 = aux1.concat(values[i].data)
table.push(aux1);
}
var rows = this.transpose(table);
var data = google.visualization.arrayToDataTable(
rows
);
var columns = [];
var series = {};
for (var i = 0; i < data.getNumberOfColumns(); i++) {
columns.push(i);
if (i > 0) {
series[i - 1] = {};
}
}
var options = {
legend: { position: 'top' },
//chartArea: { 'width': '85%', 'height': '80%' },
series: {
},
title: title,
vAxes: {
0: {
},
},
};
var chart = new google.visualization.LineChart(
document.getElementById(div));
chart.draw(data, options);
google.visualization.events.addListener(chart, 'select', function () {
var sel = chart.getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (typeof sel[0].row === 'undefined'
|| sel[0].row == null) {
var col = sel[0].column;
if (columns[col] == col) {
// hide the data series
columns[col] = {
label: data.getColumnLabel(col),
type: data.getColumnType(col),
calc: function () {
return null;
}
};
// grey out the legend entry
series[col - 1].color = '#CCCCCC';
}
else {
// show the data series
columns[col] = col;
series[col - 1].color = null;
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
}
});
}
this.drawLinePositiveChart = function (labels, values, div) {
var table = [];
var aux = ['void'];
aux = aux.concat(labels);
table.push(aux);
for (var i = 0; i < values.length; i++) {
var aux1 = [];
aux1.push(values[i].label);
aux1 = aux1.concat(values[i].data)
table.push(aux1);
}
var rows = this.transpose(table);
var data = google.visualization.arrayToDataTable(
rows
);
var columns = [];
var series = {};
for (var i = 0; i < data.getNumberOfColumns(); i++) {
columns.push(i);
if (i > 0) {
series[i - 1] = {};
}
}
var options = {
pointSize: 5,
colors: ['#1ABB9C'],
legend: { position: 'top' },
//chartArea: { 'width': '85%', 'height': '80%' },
series: {
0: { targetAxisIndex: 0 },
},
vAxes: {
0: {
viewWindowMode: "explicit",
viewWindow: { min: 0 }
},
},
};
var chart = new google.visualization.LineChart(
document.getElementById(div));
chart.draw(data, options);
google.visualization.events.addListener(chart, 'select', function () {
var sel = chart.getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (typeof sel[0].row === 'undefined'
|| sel[0].row == null) {
var col = sel[0].column;
if (columns[col] == col) {
// hide the data series
columns[col] = {
label: data.getColumnLabel(col),
type: data.getColumnType(col),
calc: function () {
return null;
}
};
// grey out the legend entry
series[col - 1].color = '#CCCCCC';
}
else {
// show the data series
columns[col] = col;
series[col - 1].color = null;
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
}
});
}
this.drawPieChart = function (values, div) {
var table = [];
var aux = ['void', 'Euros'];
table.push(aux);
for (var i = 0; i < values.length; i++) {
var aux1 = [];
aux1.push(values[i].label);
aux1 = aux1.concat(values[i].value)
table.push(aux1);
}
var data = google.visualization.arrayToDataTable(
table
);
var chart = new google.visualization.PieChart(
document.getElementById(div));
var options = {
hAxis: {
title: '',
},
vAxis: {
title: ''
},
legend: {
position: 'top'
},
//chartArea: {
// 'width': '85%', 'height': '80%'
//},
//sliceVisibilityThreshold: .15
};
chart.draw(data, options);
}
this.drawPieChartLib = function (values, div) {
var table = [];
var aux = ['void', 'Data'];
table.push(aux);
for (var i = 0; i < values.Labels.length; i++) {
var aux1 = [];
aux1.push(values.Labels[i]);
aux1 = aux1.concat(values.Series[0].Values[i])
table.push(aux1);
}
var data = google.visualization.arrayToDataTable(
table
);
var chart = new google.visualization.PieChart(
document.getElementById(div));
var options = values.Options;
chart.draw(data, options);
}
this.getColor = function (index) {
switch (index % 6) {
case (0):
return "rgba(031, 157, 212, 0.4)";
case (1):
return "rgba(193, 02, 163, 0.4)";
case (2):
return "rgba(163, 193, 02, 0.4)";
case (3):
return "rgba(02, 68, 193, 0.4)";
case (4):
return "rgba(02, 193, 128,0.4)";
case (5):
return "rgba(193, 32, 02, 0.4)";
}
}
this.getSolidColor = function (index) {
switch (index % 6) {
case (0):
return "rgba(031, 157, 212, 1)";
case (1):
return "rgba(193, 02, 163, 1)";
case (2):
return "rgba(163, 193, 02, 1)";
case (3):
return "rgba(02, 68, 193, 1)";
case (4):
return "rgba(02, 193, 128,1)";
case (5):
return "rgba(193, 32, 02, 1)";
}
}
//Metodo de transpose para representas las gráficas
this.transpose = function (table) {
// Calculate the width and height of the Array
var a = table,
w = a.length ? a.length : 0,
h = a[0] instanceof Array ? a[0].length : 0;
// In case it is a zero matrix, no transpose routine needed.
if (h === 0 || w === 0) { return []; }
/**
* @var {Number} i Counter
* @var {Number} j Counter
* @var {Array} t Transposed data is stored in this array.
*/
var i, j, t = [];
// Loop through every item in the outer array (height)
for (i = 0; i < h; i++) {
// Insert a new row (array)
t[i] = [];
// Loop through every item per item in outer array (width)
for (j = 0; j < w; j++) {
// Save transposed data.
t[i][j] = a[j][i];
}
}
return t;
};
//Metodo para inicializar las graficas de google.
//Recibe como parametro una función para pintar las graficas que se quieran
this.initCharts = function (printCharts) {
// Load the Visualization API and the corechart package.
google.charts.load('current', { 'packages': ['corechart'] });
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(printCharts);
}
this.formatDataToPrint = function (values) {
var table = [];
var aux = ['void'];
aux = aux.concat(values.Labels);
table.push(aux);
for (var i = 0; i < values.Series.length; i++) {
var aux1 = [];
aux1.push(values.Series[i].Legend);
aux1 = aux1.concat(values.Series[i].Values);
table.push(aux1);
}
var rows = this.transpose(table);
var data = google.visualization.arrayToDataTable(
rows
);
return data;
}
this.printMultiChart = function (div, values) {
var data = this.formatDataToPrint(values);
var options = values.Options;
var chart = new google.visualization.ComboChart(
document.getElementById(div));
var columns = [];
var series = {};
for (var i = 0; i < data.getNumberOfColumns(); i++) {
columns.push(i);
if (i > 0) {
series[i - 1] = {};
}
}
chart.draw(data, options);
google.visualization.events.addListener(chart, 'select', function () {
var sel = chart.getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (typeof sel[0].row === 'undefined'
|| sel[0].row == null) {
var col = sel[0].column;
if (columns[col] == col) {
// hide the data series
columns[col] = {
label: data.getColumnLabel(col),
type: data.getColumnType(col),
calc: function () {
return null;
}
};
// grey out the legend entry
series[col - 1].color = '#CCCCCC';
}
else {
// show the data series
columns[col] = col;
series[col - 1].color = null;
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
}
});
};
}]);
})();
(function () {
'use strict';
var ngLookupsService = angular.module('ngLookupsService', ['ngResource']);
ngLookupsService.service('Lookups', ['$resource', function ($resource) {
// --- General Purpouses ---
this.getAllCities = function (filter, prefix) {
return $resource(prefix + '/webapi/cities/:flt', { flt: filter },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
this.getAllAirports = function (filter, prefix) {
return $resource(prefix + '/webapi/airport/:flt', { flt: filter },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
this.getCityByName = function (filter, prefix) {
return $resource(prefix + '/webapi/citybyname/:flt', { flt: filter },
{
query: { method: 'GET', params: {}, isArray: false }
}).query().$promise;
};
this.getCountries = function (filter, prefix) {
return $resource(prefix + '/webapi/countries/:flt', { flt: filter },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
this.getPartners = function (filter, prefix) {
return $resource(prefix + '/webapi/partners/:flt', { flt: filter },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
this.getAgenciesByPartner = function (partnerUid, filter, withRef, prefix) {
return $resource(prefix + '/webapi/agencies/:pe/:flt/:wr', { pe: partnerUid, flt: filter, wr: withRef },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
this.getProviders = function (filter, prefix) {
var filterBase64 = btoa(filter);
return $resource(prefix + '/webapi/providers/:flt', { flt: filterBase64 },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
this.getAllDomains = function (filter, prefix) {
return $resource(prefix + '/webapi/domains/:flt', { flt: filter },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
// --- End General Purpouses ---
// --- Professional Registration ---
this.getRegistrationLanguages = function (filter, prefix, simplified) {
return $resource(prefix + '/webapi/internaldashboard/languages/:sim/:flt', { sim: simplified, flt: filter },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
// --- End Professional Registration ---
this.getUserPurchaseServices = function (cityName, countryCode, prefix) {
return $resource(prefix + '/webapi/userpurchase/services/:city/:ctry', { city: cityName, ctry: countryCode },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
this.getUserPurchaseAirports = function (cityName, countryCode, prefix) {
return $resource(prefix + '/webapi/userpurchase/airports/:city/:ctry', { city: cityName, ctry: countryCode },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
this.getPurchaseLanguages = function (filter, simplified, prefix) {
return $resource(prefix + '/webapi/v2/purchases/availablelanguages?filter=:flt&simplified=:sim', { sim: simplified, flt: filter },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
// --- End User Purchase ---
}]);
})();
(function () {
'use strict';
var ngPurchasesService = angular.module('ngPurchasesService', ['ngResource']);
ngPurchasesService.service('Purchases', ['$resource', function ($resource) {
this.getMeetingPointAddressesCart = function (filter, prefix, latitude, longitude, radious) {
return $resource(prefix + '/webapi/v2/purchases/meetingpointaddressescart?filter=:flt&latitude=:lat&longitude=:long&radious=:rad', { flt: filter, lat: latitude, long: longitude, rad: radious },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
// Services
this.getMaterializedServices = function (filters, rqType, partner, rqId, prefix, skip, take, currencyCode, agentUid) {
return $resource(prefix + '/webapi/v2/userpurchase/materializedservices', {},
{
query: {
method: 'POST',
params: {
filterData: filters,
partnerCode: partner,
currencyCode: currencyCode,
rqType: rqType,
rqId: rqId,
skip: skip,
take: take,
agentUid: agentUid
}, isArray: false
}
}).query().$promise;
};
// Services
this.getActivityMaterializedServicesByIds = function (ids, date, partner, rqId, prefix, mainId, sortType, currencyCode) {
return $resource(prefix + '/webapi/v2/userpurchase/activitymaterializedservicesbylist', {},
{
query: {
method: 'POST',
params: {
ids: ids,
mainId: mainId,
date: date,
rqId: rqId,
partnerCode: partner,
sortType: sortType,
currencyCode: currencyCode
}, isArray: false
}
}).query().$promise;
};
this.getApartmentsFullInformation = function (materializedlist, prefix) {
return $resource(prefix + '/webapi/v2/userpurchase/apartments', {},
{
query: {
method: 'POST',
params: {
materializeduids: materializedlist,
},
isArray: true,
}
}).query().$promise;
};
this.getActivitiesFullInformation = function (materializedlist, currencyCode, prefix) {
return $resource(prefix + '/webapi/v2/userpurchase/activities', {},
{
query: {
method: 'POST',
params: {
materializeduids: materializedlist,
currencyCode: currencyCode,
},
isArray: true,
}
}).query().$promise;
};
this.getActivityCoverData = function (prefix, partner, currencyCode) {
return $resource(prefix + '/webapi/v2/userpurchase/activitycoverdata', {},
{
query: {
method: 'POST',
params: { partnerCode: partner, currencyCode: currencyCode },
isArray: false
}
}).query().$promise;
};
this.getActivityLanguages = function (prefix) {
return $resource(prefix + '/webapi/v2/purchases/activityavailablelanguages',
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
//Only addresses, streets, stablishment
this.getAddressesPrediction = function (filter, placeId, prefix, session) {
return $resource(prefix + '/webapi/v2/userpurchase/addressesprediction?filter=:filter&placeId=:placeId&sessionToken=:session', { filter: filter, placeId: placeId, session: session },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
this.getAddressesPickup = function (filter, prefix) {
return $resource(prefix + '/webapi/v2/purchases/addressespickup?filter=:filter', { filter: filter},
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
//Only cities/regions
this.getDestinationPrediction = function (filter, prefix) {
return $resource(prefix + '/webapi/v2/userpurchase/destinationprediction?filter=:filter', { filter: filter },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
//Addresses and cities
this.getUserPurchaseAddresses = function (filter, prefix, cityName, countryCode, serviceCode) {
return $resource(prefix + '/webapi/v2/userpurchase/addresses?filter=:flt&cityName=:city&countryCode=:country&serviceCode=:srv', { flt: filter, city: cityName, country: countryCode, srv: serviceCode },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
//Airports
this.getAirportsToComplete = function (filter) {
return $resource('/webapi/v2/userpurchase/airport?filter=:filter', { filter: filter },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
//Cities/Venues
this.getActivitiesDestinationPrediction = function (filter, prefix, placeId) {
return $resource(prefix + '/webapi/v2/userpurchase/activitiesdestinationprediction?filter=:filter&placeId=:placeId', { filter: filter, placeId: placeId },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
this.getActivitiesDestinationPredictionWhitoutRegions = function (filter, prefix, placeId) {
return $resource(prefix + '/webapi/v2/userpurchase/activitiesdestinationpredictionwithoutregions?filter=:filter&placeId=:placeId', { filter: filter, placeId: placeId },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
//this.getApartmentsDestinationPrediction = function (filter, prefix, placeId) {
// return $resource(prefix + '/webapi/v2/userpurchase/apartmentsdestinationprediction?filter=:filter&placeId=:placeId', { filter: filter, placeId: placeId },
// {
// query: { method: 'GET', params: {}, isArray: true }
// }).query().$promise;
//};
this.getApartmentsDestinationPrediction = function (filter, placeId, prefix, session) {
return $resource(prefix + '/webapi/v2/userpurchase/apartmentsdestinationprediction?filter=:filter&placeId=:placeId&sessionToken=:session', { filter: filter, placeId: placeId, session: session },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
//Internal purchase
this.getPurchaseInternalAvailableServices = function (mainService, prefix) {
return $resource(prefix + '/webapi/v2/internaldashboard/availableinternalservices?mainService=:srv', { srv: mainService },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
this.getPurchaseInternalApartmentCategories = function (prefix) {
return $resource(prefix + '/webapi/v2/internaldashboard/availableinternalapartmentcategories',
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
this.getPuchaseInternalCurrencies = function (prefix) {
return $resource(prefix + '/webapi/v2/internaldashboard/currencies',
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
this.getFlightInfo = function (filter, date, dateArr, prefix, iataOrigin, iataDestination) {
return $resource(prefix + '/webapi/v2/purchases/flightInfo', {},
{
query: {
method: 'POST',
params: {
filter: filter,
departureDate: date,
arrivalDate: dateArr,
iataOrigin: iataOrigin,
iataDestination: iataDestination
}, isArray: false
}
}).query().$promise;
};
//////
function transformGetToInt(json, headerGetter) {
var fromJson = angular.fromJson({ raw: json });
return fromJson;
}
}]);
})();
(function () {
'use strict';
var ngTabulatorHelperService = angular.module('ngTabulatorHelperService', ['ngResource']);
ngTabulatorHelperService.service('TabulatorHelper', ['$resource', '$http', function ($resource) {
this.setDefaultCell = function (cell) {
//Put default params color for the cell.
cell.addClass("tb-default-cell");
};
this.setModifiedCell = function (cell) {
//Put modified color to the cell.
cell.addClass("tb-modified-cell");
};
//custom header filter
this.dateFilterEditor = function(cell, onRendered, success, cancel, editorParams) {
var container = $(" ")
//create and style input
var selectfield = $("" +
'Future reservations ' +
'Past reservations ' +
'Beetween reservations ' +
+
" ");
var start = $(" ");
var end = $(" ");
container.append(selectfield).append(start).append(end);
var inputs = $("input", container);
inputs.css({
"padding": "4px",
"width": "50%",
"box-sizing": "border-box",
})
.val(cell.getValue());
function buildDateString() {
var json = { type:selectfield.val(), start: start.val(), end: end.val() };
return JSON.stringify(json);
}
function buildTypeString() {
var json = { type:selectfield.val()};
return JSON.stringify(json);
}
selectfield.change(function() {
var selectvalue = selectfield.val();
if (selectvalue != "beetween_reservations") {
start.val("");
end.val("");
start.hide();
end.hide();
success(buildTypeString());
} else {
start.show();
end.show();
}
});
//submit new value on blur
inputs.on("change blur",
function(e) {
success(buildDateString());
});
//submit new value on enter
inputs.on("keydown",
function(e) {
if (e.keyCode == 13) {
success(buildDateString());
}
if (e.keyCode == 27) {
cancel();
}
});
return container;
};
//custom filter function
this.dateFilterFunction=function(headerValue, rowValue, rowData, filterParams){
//headerValue - the value of the header filter element
//rowValue - the value of the column in this row
//rowData - the data for the row being filtered
//filterParams - params object passed to the headerFilterFuncParams property
var format = filterParams.format || "DD/MM/YYYY";
var start = moment(headerValue.start);
var end = moment(headerValue.end);
var value = moment(rowValue, format)
if(rowValue){
if(start.isValid()){
if(end.isValid()){
return value >= start && value <= end;
}else{
return value >= start;
}
}else{
if(end.isValid()){
return value <= end;
}
}
}
return false; //must return a boolean, true if it passes the filter.
} }]);
})();
(function () {
'use strict';
var ngValidationsService = angular.module('ngValidationsService', ['ngResource']);
ngValidationsService.service('Validations', ['$resource', function ($resource) {
this.existsUserEmail = function (email, prefix) {
return $resource(prefix + '/webapi/registrationvalidation/email/:mail', { mail: email },
{
get: { method: 'GET', transformResponse: transformGetToBoolean },
}).get().$promise;
};
this.existsPartnerEmail = function (email, prefix) {
return $resource(prefix + '/webapi/registrationpartnervalidation/email/:mail', { mail: email },
{
get: { method: 'GET', transformResponse: transformGetToBoolean },
}).get().$promise;
};
this.existsClientEmail = function (email, prefix) {
if (email == undefined || email.length == 0)
return;
return $resource(prefix + '/webapi/clientregistrationvalidation/email/:mail/', { mail: email },
{
get: { method: 'GET', transformResponse: transformGetToBoolean },
}).get().$promise;
};
this.existsCompanyVat = function (vatnumber, prefix) {
return $resource(prefix + '/webapi/registrationvalidation/vatnumber/:vatnumber', { vatnumber: vatnumber },
{
get: { method: 'GET', transformResponse: transformGetToBoolean },
}).get().$promise;
};
this.existsInternalUserEmail = function (email, prefix) {
return $resource(prefix + '/webapi/internaluserregistrationvalidation/email/:mail', { mail: email },
{
get: { method: 'GET', transformResponse: transformGetToBoolean },
}).get().$promise;
};
this.existsUserEmailInternalDashboard = function (email, prefix) {
return $resource(prefix + '/webapi/registerprofessionalvalidation/email/:mail', { mail: email },
{
get: { method: 'GET', transformResponse: transformGetToBoolean },
}).get().$promise;
};
this.existsDiscountCode = function (code, prefix) {
return $resource(prefix + '/webapi/internaldiscountvalidation/discountCode/:discountCode', { discountCode: code },
{
get: { method: 'GET', transformResponse: transformGetToBoolean },
}).get().$promise;
};
}]);
function transformGetToBoolean(json, headerGetter) {
var fromJson = angular.fromJson({ raw: (json === "true") });
return fromJson;
}
})();
/**!
* AngularJS file upload directives and services. Supports: file upload/drop/paste, resume, cancel/abort,
* progress, resize, thumbnail, preview, validation and CORS
* FileAPI Flash shim for old browsers not supporting FormData
* @author Danial
* @version 12.2.13
*/
(function () {
/** @namespace FileAPI.noContentTimeout */
function patchXHR(fnName, newFn) {
window.XMLHttpRequest.prototype[fnName] = newFn(window.XMLHttpRequest.prototype[fnName]);
}
function redefineProp(xhr, prop, fn) {
try {
Object.defineProperty(xhr, prop, { get: fn });
} catch (e) {/*ignore*/
}
}
if (!window.FileAPI) {
window.FileAPI = {};
}
if (!window.XMLHttpRequest) {
throw 'AJAX is not supported. XMLHttpRequest is not defined.';
}
FileAPI.shouldLoad = !window.FormData || FileAPI.forceLoad;
if (FileAPI.shouldLoad) {
var initializeUploadListener = function (xhr) {
if (!xhr.__listeners) {
if (!xhr.upload) xhr.upload = {};
xhr.__listeners = [];
var origAddEventListener = xhr.upload.addEventListener;
xhr.upload.addEventListener = function (t, fn) {
xhr.__listeners[t] = fn;
if (origAddEventListener) origAddEventListener.apply(this, arguments);
};
}
};
patchXHR('open', function (orig) {
return function (m, url, b) {
initializeUploadListener(this);
this.__url = url;
try {
orig.apply(this, [m, url, b]);
} catch (e) {
if (e.message.indexOf('Access is denied') > -1) {
this.__origError = e;
orig.apply(this, [m, '_fix_for_ie_crossdomain__', b]);
}
}
};
});
patchXHR('getResponseHeader', function (orig) {
return function (h) {
return this.__fileApiXHR && this.__fileApiXHR.getResponseHeader ? this.__fileApiXHR.getResponseHeader(h) : (orig == null ? null : orig.apply(this, [h]));
};
});
patchXHR('getAllResponseHeaders', function (orig) {
return function () {
return this.__fileApiXHR && this.__fileApiXHR.getAllResponseHeaders ? this.__fileApiXHR.getAllResponseHeaders() : (orig == null ? null : orig.apply(this));
};
});
patchXHR('abort', function (orig) {
return function () {
return this.__fileApiXHR && this.__fileApiXHR.abort ? this.__fileApiXHR.abort() : (orig == null ? null : orig.apply(this));
};
});
patchXHR('setRequestHeader', function (orig) {
return function (header, value) {
if (header === '__setXHR_') {
initializeUploadListener(this);
var val = value(this);
// fix for angular < 1.2.0
if (val instanceof Function) {
val(this);
}
} else {
this.__requestHeaders = this.__requestHeaders || {};
this.__requestHeaders[header] = value;
orig.apply(this, arguments);
}
};
});
patchXHR('send', function (orig) {
return function () {
var xhr = this;
if (arguments[0] && arguments[0].__isFileAPIShim) {
var formData = arguments[0];
var config = {
url: xhr.__url,
jsonp: false, //removes the callback form param
cache: true, //removes the ?fileapiXXX in the url
complete: function (err, fileApiXHR) {
if (err && angular.isString(err) && err.indexOf('#2174') !== -1) {
// this error seems to be fine the file is being uploaded properly.
err = null;
}
xhr.__completed = true;
if (!err && xhr.__listeners.load)
xhr.__listeners.load({
type: 'load',
loaded: xhr.__loaded,
total: xhr.__total,
target: xhr,
lengthComputable: true
});
if (!err && xhr.__listeners.loadend)
xhr.__listeners.loadend({
type: 'loadend',
loaded: xhr.__loaded,
total: xhr.__total,
target: xhr,
lengthComputable: true
});
if (err === 'abort' && xhr.__listeners.abort)
xhr.__listeners.abort({
type: 'abort',
loaded: xhr.__loaded,
total: xhr.__total,
target: xhr,
lengthComputable: true
});
if (fileApiXHR.status !== undefined) redefineProp(xhr, 'status', function () {
return (fileApiXHR.status === 0 && err && err !== 'abort') ? 500 : fileApiXHR.status;
});
if (fileApiXHR.statusText !== undefined) redefineProp(xhr, 'statusText', function () {
return fileApiXHR.statusText;
});
redefineProp(xhr, 'readyState', function () {
return 4;
});
if (fileApiXHR.response !== undefined) redefineProp(xhr, 'response', function () {
return fileApiXHR.response;
});
var resp = fileApiXHR.responseText || (err && fileApiXHR.status === 0 && err !== 'abort' ? err : undefined);
redefineProp(xhr, 'responseText', function () {
return resp;
});
redefineProp(xhr, 'response', function () {
return resp;
});
if (err) redefineProp(xhr, 'err', function () {
return err;
});
xhr.__fileApiXHR = fileApiXHR;
if (xhr.onreadystatechange) xhr.onreadystatechange();
if (xhr.onload) xhr.onload();
},
progress: function (e) {
e.target = xhr;
if (xhr.__listeners.progress) xhr.__listeners.progress(e);
xhr.__total = e.total;
xhr.__loaded = e.loaded;
if (e.total === e.loaded) {
// fix flash issue that doesn't call complete if there is no response text from the server
var _this = this;
setTimeout(function () {
if (!xhr.__completed) {
xhr.getAllResponseHeaders = function () {
};
_this.complete(null, { status: 204, statusText: 'No Content' });
}
}, FileAPI.noContentTimeout || 10000);
}
},
headers: xhr.__requestHeaders
};
config.data = {};
config.files = {};
for (var i = 0; i < formData.data.length; i++) {
var item = formData.data[i];
if (item.val != null && item.val.name != null && item.val.size != null && item.val.type != null) {
config.files[item.key] = item.val;
} else {
config.data[item.key] = item.val;
}
}
setTimeout(function () {
if (!FileAPI.hasFlash) {
throw 'Adode Flash Player need to be installed. To check ahead use "FileAPI.hasFlash"';
}
xhr.__fileApiXHR = FileAPI.upload(config);
}, 1);
} else {
if (this.__origError) {
throw this.__origError;
}
orig.apply(xhr, arguments);
}
};
});
window.XMLHttpRequest.__isFileAPIShim = true;
window.FormData = FormData = function () {
return {
append: function (key, val, name) {
if (val.__isFileAPIBlobShim) {
val = val.data[0];
}
this.data.push({
key: key,
val: val,
name: name
});
},
data: [],
__isFileAPIShim: true
};
};
window.Blob = Blob = function (b) {
return {
data: b,
__isFileAPIBlobShim: true
};
};
}
})();
(function () {
/** @namespace FileAPI.forceLoad */
/** @namespace window.FileAPI.jsUrl */
/** @namespace window.FileAPI.jsPath */
function isInputTypeFile(elem) {
return elem[0].tagName.toLowerCase() === 'input' && elem.attr('type') && elem.attr('type').toLowerCase() === 'file';
}
function hasFlash() {
try {
var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
if (fo) return true;
} catch (e) {
if (navigator.mimeTypes['application/x-shockwave-flash'] !== undefined) return true;
}
return false;
}
function getOffset(obj) {
var left = 0, top = 0;
if (window.jQuery) {
return jQuery(obj).offset();
}
if (obj.offsetParent) {
do {
left += (obj.offsetLeft - obj.scrollLeft);
top += (obj.offsetTop - obj.scrollTop);
obj = obj.offsetParent;
} while (obj);
}
return {
left: left,
top: top
};
}
if (FileAPI.shouldLoad) {
FileAPI.hasFlash = hasFlash();
//load FileAPI
if (FileAPI.forceLoad) {
FileAPI.html5 = false;
}
if (!FileAPI.upload) {
var jsUrl, basePath, script = document.createElement('script'), allScripts = document.getElementsByTagName('script'), i, index, src;
if (window.FileAPI.jsUrl) {
jsUrl = window.FileAPI.jsUrl;
} else if (window.FileAPI.jsPath) {
basePath = window.FileAPI.jsPath;
} else {
for (i = 0; i < allScripts.length; i++) {
src = allScripts[i].src;
index = src.search(/\/ng\-file\-upload[\-a-zA-z0-9\.]*\.js/);
if (index > -1) {
basePath = src.substring(0, index + 1);
break;
}
}
}
if (FileAPI.staticPath == null) FileAPI.staticPath = basePath;
script.setAttribute('src', jsUrl || basePath + 'FileAPI.min.js');
document.getElementsByTagName('head')[0].appendChild(script);
}
FileAPI.ngfFixIE = function (elem, fileElem, changeFn) {
if (!hasFlash()) {
throw 'Adode Flash Player need to be installed. To check ahead use "FileAPI.hasFlash"';
}
var fixInputStyle = function () {
var label = fileElem.parent();
if (elem.attr('disabled')) {
if (label) label.removeClass('js-fileapi-wrapper');
} else {
if (!fileElem.attr('__ngf_flash_')) {
fileElem.unbind('change');
fileElem.unbind('click');
fileElem.bind('change', function (evt) {
fileApiChangeFn.apply(this, [evt]);
changeFn.apply(this, [evt]);
});
fileElem.attr('__ngf_flash_', 'true');
}
label.addClass('js-fileapi-wrapper');
if (!isInputTypeFile(elem)) {
label.css('position', 'absolute')
.css('top', getOffset(elem[0]).top + 'px').css('left', getOffset(elem[0]).left + 'px')
.css('width', elem[0].offsetWidth + 'px').css('height', elem[0].offsetHeight + 'px')
.css('filter', 'alpha(opacity=0)').css('display', elem.css('display'))
.css('overflow', 'hidden').css('z-index', '900000')
.css('visibility', 'visible');
fileElem.css('width', elem[0].offsetWidth + 'px').css('height', elem[0].offsetHeight + 'px')
.css('position', 'absolute').css('top', '0px').css('left', '0px');
}
}
};
elem.bind('mouseenter', fixInputStyle);
var fileApiChangeFn = function (evt) {
var files = FileAPI.getFiles(evt);
//just a double check for #233
for (var i = 0; i < files.length; i++) {
if (files[i].size === undefined) files[i].size = 0;
if (files[i].name === undefined) files[i].name = 'file';
if (files[i].type === undefined) files[i].type = 'undefined';
}
if (!evt.target) {
evt.target = {};
}
evt.target.files = files;
// if evt.target.files is not writable use helper field
if (evt.target.files !== files) {
evt.__files_ = files;
}
(evt.__files_ || evt.target.files).item = function (i) {
return (evt.__files_ || evt.target.files)[i] || null;
};
};
};
FileAPI.disableFileInput = function (elem, disable) {
if (disable) {
elem.removeClass('js-fileapi-wrapper');
} else {
elem.addClass('js-fileapi-wrapper');
}
};
}
})();
if (!window.FileReader) {
window.FileReader = function () {
var _this = this, loadStarted = false;
this.listeners = {};
this.addEventListener = function (type, fn) {
_this.listeners[type] = _this.listeners[type] || [];
_this.listeners[type].push(fn);
};
this.removeEventListener = function (type, fn) {
if (_this.listeners[type]) _this.listeners[type].splice(_this.listeners[type].indexOf(fn), 1);
};
this.dispatchEvent = function (evt) {
var list = _this.listeners[evt.type];
if (list) {
for (var i = 0; i < list.length; i++) {
list[i].call(_this, evt);
}
}
};
this.onabort = this.onerror = this.onload = this.onloadstart = this.onloadend = this.onprogress = null;
var constructEvent = function (type, evt) {
var e = { type: type, target: _this, loaded: evt.loaded, total: evt.total, error: evt.error };
if (evt.result != null) e.target.result = evt.result;
return e;
};
var listener = function (evt) {
if (!loadStarted) {
loadStarted = true;
if (_this.onloadstart) _this.onloadstart(constructEvent('loadstart', evt));
}
var e;
if (evt.type === 'load') {
if (_this.onloadend) _this.onloadend(constructEvent('loadend', evt));
e = constructEvent('load', evt);
if (_this.onload) _this.onload(e);
_this.dispatchEvent(e);
} else if (evt.type === 'progress') {
e = constructEvent('progress', evt);
if (_this.onprogress) _this.onprogress(e);
_this.dispatchEvent(e);
} else {
e = constructEvent('error', evt);
if (_this.onerror) _this.onerror(e);
_this.dispatchEvent(e);
}
};
this.readAsDataURL = function (file) {
FileAPI.readAsDataURL(file, listener);
};
this.readAsText = function (file) {
FileAPI.readAsText(file, listener);
};
};
}
/**!
* AngularJS file upload directives and services. Supoorts: file upload/drop/paste, resume, cancel/abort,
* progress, resize, thumbnail, preview, validation and CORS
* @author Danial
* @version 12.2.13
*/
if (window.XMLHttpRequest && !(window.FileAPI && FileAPI.shouldLoad)) {
window.XMLHttpRequest.prototype.setRequestHeader = (function (orig) {
return function (header, value) {
if (header === '__setXHR_') {
var val = value(this);
// fix for angular < 1.2.0
if (val instanceof Function) {
val(this);
}
} else {
orig.apply(this, arguments);
}
};
})(window.XMLHttpRequest.prototype.setRequestHeader);
}
var ngFileUpload = angular.module('ngFileUpload', []);
ngFileUpload.version = '12.2.13';
ngFileUpload.service('UploadBase', ['$http', '$q', '$timeout', function ($http, $q, $timeout) {
var upload = this;
upload.promisesCount = 0;
this.isResumeSupported = function () {
return window.Blob && window.Blob.prototype.slice;
};
var resumeSupported = this.isResumeSupported();
function sendHttp(config) {
config.method = config.method || 'POST';
config.headers = config.headers || {};
var deferred = config._deferred = config._deferred || $q.defer();
var promise = deferred.promise;
function notifyProgress(e) {
if (deferred.notify) {
deferred.notify(e);
}
if (promise.progressFunc) {
$timeout(function () {
promise.progressFunc(e);
});
}
}
function getNotifyEvent(n) {
if (config._start != null && resumeSupported) {
return {
loaded: n.loaded + config._start,
total: (config._file && config._file.size) || n.total,
type: n.type, config: config,
lengthComputable: true, target: n.target
};
} else {
return n;
}
}
if (!config.disableProgress) {
config.headers.__setXHR_ = function () {
return function (xhr) {
if (!xhr || !xhr.upload || !xhr.upload.addEventListener) return;
config.__XHR = xhr;
if (config.xhrFn) config.xhrFn(xhr);
xhr.upload.addEventListener('progress', function (e) {
e.config = config;
notifyProgress(getNotifyEvent(e));
}, false);
//fix for firefox not firing upload progress end, also IE8-9
xhr.upload.addEventListener('load', function (e) {
if (e.lengthComputable) {
e.config = config;
notifyProgress(getNotifyEvent(e));
}
}, false);
};
};
}
function uploadWithAngular() {
$http(config).then(function (r) {
if (resumeSupported && config._chunkSize && !config._finished && config._file) {
var fileSize = config._file && config._file.size || 0;
notifyProgress({
loaded: Math.min(config._end, fileSize),
total: fileSize,
config: config,
type: 'progress'
}
);
upload.upload(config, true);
} else {
if (config._finished) delete config._finished;
deferred.resolve(r);
}
}, function (e) {
deferred.reject(e);
}, function (n) {
deferred.notify(n);
}
);
}
if (!resumeSupported) {
uploadWithAngular();
} else if (config._chunkSize && config._end && !config._finished) {
config._start = config._end;
config._end += config._chunkSize;
uploadWithAngular();
} else if (config.resumeSizeUrl) {
$http.get(config.resumeSizeUrl).then(function (resp) {
if (config.resumeSizeResponseReader) {
config._start = config.resumeSizeResponseReader(resp.data);
} else {
config._start = parseInt((resp.data.size == null ? resp.data : resp.data.size).toString());
}
if (config._chunkSize) {
config._end = config._start + config._chunkSize;
}
uploadWithAngular();
}, function (e) {
throw e;
});
} else if (config.resumeSize) {
config.resumeSize().then(function (size) {
config._start = size;
if (config._chunkSize) {
config._end = config._start + config._chunkSize;
}
uploadWithAngular();
}, function (e) {
throw e;
});
} else {
if (config._chunkSize) {
config._start = 0;
config._end = config._start + config._chunkSize;
}
uploadWithAngular();
}
promise.success = function (fn) {
promise.then(function (response) {
fn(response.data, response.status, response.headers, config);
});
return promise;
};
promise.error = function (fn) {
promise.then(null, function (response) {
fn(response.data, response.status, response.headers, config);
});
return promise;
};
promise.progress = function (fn) {
promise.progressFunc = fn;
promise.then(null, null, function (n) {
fn(n);
});
return promise;
};
promise.abort = promise.pause = function () {
if (config.__XHR) {
$timeout(function () {
config.__XHR.abort();
});
}
return promise;
};
promise.xhr = function (fn) {
config.xhrFn = (function (origXhrFn) {
return function () {
if (origXhrFn) origXhrFn.apply(promise, arguments);
fn.apply(promise, arguments);
};
})(config.xhrFn);
return promise;
};
upload.promisesCount++;
if (promise['finally'] && promise['finally'] instanceof Function) {
promise['finally'](function () {
upload.promisesCount--;
});
}
return promise;
}
this.isUploadInProgress = function () {
return upload.promisesCount > 0;
};
this.rename = function (file, name) {
file.ngfName = name;
return file;
};
this.jsonBlob = function (val) {
if (val != null && !angular.isString(val)) {
val = JSON.stringify(val);
}
var blob = new window.Blob([val], { type: 'application/json' });
blob._ngfBlob = true;
return blob;
};
this.json = function (val) {
return angular.toJson(val);
};
function copy(obj) {
var clone = {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = obj[key];
}
}
return clone;
}
this.isFile = function (file) {
return file != null && (file instanceof window.Blob || (file.flashId && file.name && file.size));
};
this.upload = function (config, internal) {
function toResumeFile(file, formData) {
if (file._ngfBlob) return file;
config._file = config._file || file;
if (config._start != null && resumeSupported) {
if (config._end && config._end >= file.size) {
config._finished = true;
config._end = file.size;
}
var slice = file.slice(config._start, config._end || file.size);
slice.name = file.name;
slice.ngfName = file.ngfName;
if (config._chunkSize) {
formData.append('_chunkSize', config._chunkSize);
formData.append('_currentChunkSize', config._end - config._start);
formData.append('_chunkNumber', Math.floor(config._start / config._chunkSize));
formData.append('_totalSize', config._file.size);
}
return slice;
}
return file;
}
function addFieldToFormData(formData, val, key) {
if (val !== undefined) {
if (angular.isDate(val)) {
val = val.toISOString();
}
if (angular.isString(val)) {
formData.append(key, val);
} else if (upload.isFile(val)) {
var file = toResumeFile(val, formData);
var split = key.split(',');
if (split[1]) {
file.ngfName = split[1].replace(/^\s+|\s+$/g, '');
key = split[0];
}
config._fileKey = config._fileKey || key;
formData.append(key, file, file.ngfName || file.name);
} else {
if (angular.isObject(val)) {
if (val.$$ngfCircularDetection) throw 'ngFileUpload: Circular reference in config.data. Make sure specified data for Upload.upload() has no circular reference: ' + key;
val.$$ngfCircularDetection = true;
try {
for (var k in val) {
if (val.hasOwnProperty(k) && k !== '$$ngfCircularDetection') {
var objectKey = config.objectKey == null ? '[i]' : config.objectKey;
if (val.length && parseInt(k) > -1) {
objectKey = config.arrayKey == null ? objectKey : config.arrayKey;
}
addFieldToFormData(formData, val[k], key + objectKey.replace(/[ik]/g, k));
}
}
} finally {
delete val.$$ngfCircularDetection;
}
} else {
formData.append(key, val);
}
}
}
}
function digestConfig() {
config._chunkSize = upload.translateScalars(config.resumeChunkSize);
config._chunkSize = config._chunkSize ? parseInt(config._chunkSize.toString()) : null;
config.headers = config.headers || {};
config.headers['Content-Type'] = undefined;
config.transformRequest = config.transformRequest ?
(angular.isArray(config.transformRequest) ?
config.transformRequest : [config.transformRequest]) : [];
config.transformRequest.push(function (data) {
var formData = new window.FormData(), key;
data = data || config.fields || {};
if (config.file) {
data.file = config.file;
}
for (key in data) {
if (data.hasOwnProperty(key)) {
var val = data[key];
if (config.formDataAppender) {
config.formDataAppender(formData, key, val);
} else {
addFieldToFormData(formData, val, key);
}
}
}
return formData;
});
}
if (!internal) config = copy(config);
if (!config._isDigested) {
config._isDigested = true;
digestConfig();
}
return sendHttp(config);
};
this.http = function (config) {
config = copy(config);
config.transformRequest = config.transformRequest || function (data) {
if ((window.ArrayBuffer && data instanceof window.ArrayBuffer) || data instanceof window.Blob) {
return data;
}
return $http.defaults.transformRequest[0].apply(this, arguments);
};
config._chunkSize = upload.translateScalars(config.resumeChunkSize);
config._chunkSize = config._chunkSize ? parseInt(config._chunkSize.toString()) : null;
return sendHttp(config);
};
this.translateScalars = function (str) {
if (angular.isString(str)) {
if (str.search(/kb/i) === str.length - 2) {
return parseFloat(str.substring(0, str.length - 2) * 1024);
} else if (str.search(/mb/i) === str.length - 2) {
return parseFloat(str.substring(0, str.length - 2) * 1048576);
} else if (str.search(/gb/i) === str.length - 2) {
return parseFloat(str.substring(0, str.length - 2) * 1073741824);
} else if (str.search(/b/i) === str.length - 1) {
return parseFloat(str.substring(0, str.length - 1));
} else if (str.search(/s/i) === str.length - 1) {
return parseFloat(str.substring(0, str.length - 1));
} else if (str.search(/m/i) === str.length - 1) {
return parseFloat(str.substring(0, str.length - 1) * 60);
} else if (str.search(/h/i) === str.length - 1) {
return parseFloat(str.substring(0, str.length - 1) * 3600);
}
}
return str;
};
this.urlToBlob = function (url) {
var defer = $q.defer();
$http({ url: url, method: 'get', responseType: 'arraybuffer' }).then(function (resp) {
var arrayBufferView = new Uint8Array(resp.data);
var type = resp.headers('content-type') || 'image/WebP';
var blob = new window.Blob([arrayBufferView], { type: type });
var matches = url.match(/.*\/(.+?)(\?.*)?$/);
if (matches.length > 1) {
blob.name = matches[1];
}
defer.resolve(blob);
}, function (e) {
defer.reject(e);
});
return defer.promise;
};
this.setDefaults = function (defaults) {
this.defaults = defaults || {};
};
this.defaults = {};
this.version = ngFileUpload.version;
}
]);
ngFileUpload.service('Upload', ['$parse', '$timeout', '$compile', '$q', 'UploadExif', function ($parse, $timeout, $compile, $q, UploadExif) {
var upload = UploadExif;
upload.getAttrWithDefaults = function (attr, name) {
if (attr[name] != null) return attr[name];
var def = upload.defaults[name];
return (def == null ? def : (angular.isString(def) ? def : JSON.stringify(def)));
};
upload.attrGetter = function (name, attr, scope, params) {
var attrVal = this.getAttrWithDefaults(attr, name);
if (scope) {
try {
if (params) {
return $parse(attrVal)(scope, params);
} else {
return $parse(attrVal)(scope);
}
} catch (e) {
// hangle string value without single qoute
if (name.search(/min|max|pattern/i)) {
return attrVal;
} else {
throw e;
}
}
} else {
return attrVal;
}
};
upload.shouldUpdateOn = function (type, attr, scope) {
var modelOptions = upload.attrGetter('ngfModelOptions', attr, scope);
if (modelOptions && modelOptions.updateOn) {
return modelOptions.updateOn.split(' ').indexOf(type) > -1;
}
return true;
};
upload.emptyPromise = function () {
var d = $q.defer();
var args = arguments;
$timeout(function () {
d.resolve.apply(d, args);
});
return d.promise;
};
upload.rejectPromise = function () {
var d = $q.defer();
var args = arguments;
$timeout(function () {
d.reject.apply(d, args);
});
return d.promise;
};
upload.happyPromise = function (promise, data) {
var d = $q.defer();
promise.then(function (result) {
d.resolve(result);
}, function (error) {
$timeout(function () {
throw error;
});
d.resolve(data);
});
return d.promise;
};
function applyExifRotations(files, attr, scope) {
var promises = [upload.emptyPromise()];
angular.forEach(files, function (f, i) {
if (f.type.indexOf('image/jpeg') === 0 && upload.attrGetter('ngfFixOrientation', attr, scope, { $file: f })) {
promises.push(upload.happyPromise(upload.applyExifRotation(f), f).then(function (fixedFile) {
files.splice(i, 1, fixedFile);
}));
}
});
return $q.all(promises);
}
function resizeFile(files, attr, scope, ngModel) {
var resizeVal = upload.attrGetter('ngfResize', attr, scope);
if (!resizeVal || !upload.isResizeSupported() || !files.length) return upload.emptyPromise();
if (resizeVal instanceof Function) {
var defer = $q.defer();
return resizeVal(files).then(function (p) {
resizeWithParams(p, files, attr, scope, ngModel).then(function (r) {
defer.resolve(r);
}, function (e) {
defer.reject(e);
});
}, function (e) {
defer.reject(e);
});
} else {
return resizeWithParams(resizeVal, files, attr, scope, ngModel);
}
}
function resizeWithParams(params, files, attr, scope, ngModel) {
var promises = [upload.emptyPromise()];
function handleFile(f, i) {
if (f.type.indexOf('image') === 0) {
if (params.pattern && !upload.validatePattern(f, params.pattern)) return;
params.resizeIf = function (width, height) {
return upload.attrGetter('ngfResizeIf', attr, scope,
{ $width: width, $height: height, $file: f });
};
var promise = upload.resize(f, params);
promises.push(promise);
promise.then(function (resizedFile) {
files.splice(i, 1, resizedFile);
}, function (e) {
f.$error = 'resize';
(f.$errorMessages = (f.$errorMessages || {})).resize = true;
f.$errorParam = (e ? (e.message ? e.message : e) + ': ' : '') + (f && f.name);
ngModel.$ngfValidations.push({ name: 'resize', valid: false });
upload.applyModelValidation(ngModel, files);
});
}
}
for (var i = 0; i < files.length; i++) {
handleFile(files[i], i);
}
return $q.all(promises);
}
upload.updateModel = function (ngModel, attr, scope, fileChange, files, evt, noDelay) {
function update(files, invalidFiles, newFiles, dupFiles, isSingleModel) {
attr.$$ngfPrevValidFiles = files;
attr.$$ngfPrevInvalidFiles = invalidFiles;
var file = files && files.length ? files[0] : null;
var invalidFile = invalidFiles && invalidFiles.length ? invalidFiles[0] : null;
if (ngModel) {
upload.applyModelValidation(ngModel, files);
ngModel.$setViewValue(isSingleModel ? file : files);
}
if (fileChange) {
$parse(fileChange)(scope, {
$files: files,
$file: file,
$newFiles: newFiles,
$duplicateFiles: dupFiles,
$invalidFiles: invalidFiles,
$invalidFile: invalidFile,
$event: evt
});
}
var invalidModel = upload.attrGetter('ngfModelInvalid', attr);
if (invalidModel) {
$timeout(function () {
$parse(invalidModel).assign(scope, isSingleModel ? invalidFile : invalidFiles);
});
}
$timeout(function () {
// scope apply changes
});
}
var allNewFiles, dupFiles = [], prevValidFiles, prevInvalidFiles,
invalids = [], valids = [];
function removeDuplicates() {
function equals(f1, f2) {
return f1.name === f2.name && (f1.$ngfOrigSize || f1.size) === (f2.$ngfOrigSize || f2.size) &&
f1.type === f2.type;
}
function isInPrevFiles(f) {
var j;
for (j = 0; j < prevValidFiles.length; j++) {
if (equals(f, prevValidFiles[j])) {
return true;
}
}
for (j = 0; j < prevInvalidFiles.length; j++) {
if (equals(f, prevInvalidFiles[j])) {
return true;
}
}
return false;
}
if (files) {
allNewFiles = [];
dupFiles = [];
for (var i = 0; i < files.length; i++) {
if (isInPrevFiles(files[i])) {
dupFiles.push(files[i]);
} else {
allNewFiles.push(files[i]);
}
}
}
}
function toArray(v) {
return angular.isArray(v) ? v : [v];
}
function resizeAndUpdate() {
function updateModel() {
$timeout(function () {
update(keep ? prevValidFiles.concat(valids) : valids,
keep ? prevInvalidFiles.concat(invalids) : invalids,
files, dupFiles, isSingleModel);
}, options && options.debounce ? options.debounce.change || options.debounce : 0);
}
var resizingFiles = validateAfterResize ? allNewFiles : valids;
resizeFile(resizingFiles, attr, scope, ngModel).then(function () {
if (validateAfterResize) {
upload.validate(allNewFiles, keep ? prevValidFiles.length : 0, ngModel, attr, scope)
.then(function (validationResult) {
valids = validationResult.validsFiles;
invalids = validationResult.invalidsFiles;
updateModel();
});
} else {
updateModel();
}
}, function () {
for (var i = 0; i < resizingFiles.length; i++) {
var f = resizingFiles[i];
if (f.$error === 'resize') {
var index = valids.indexOf(f);
if (index > -1) {
valids.splice(index, 1);
invalids.push(f);
}
updateModel();
}
}
});
}
prevValidFiles = attr.$$ngfPrevValidFiles || [];
prevInvalidFiles = attr.$$ngfPrevInvalidFiles || [];
if (ngModel && ngModel.$modelValue) {
prevValidFiles = toArray(ngModel.$modelValue);
}
var keep = upload.attrGetter('ngfKeep', attr, scope);
allNewFiles = (files || []).slice(0);
if (keep === 'distinct' || upload.attrGetter('ngfKeepDistinct', attr, scope) === true) {
removeDuplicates(attr, scope);
}
var isSingleModel = !keep && !upload.attrGetter('ngfMultiple', attr, scope) && !upload.attrGetter('multiple', attr);
if (keep && !allNewFiles.length) return;
upload.attrGetter('ngfBeforeModelChange', attr, scope, {
$files: files,
$file: files && files.length ? files[0] : null,
$newFiles: allNewFiles,
$duplicateFiles: dupFiles,
$event: evt
});
var validateAfterResize = upload.attrGetter('ngfValidateAfterResize', attr, scope);
var options = upload.attrGetter('ngfModelOptions', attr, scope);
upload.validate(allNewFiles, keep ? prevValidFiles.length : 0, ngModel, attr, scope)
.then(function (validationResult) {
if (noDelay) {
update(allNewFiles, [], files, dupFiles, isSingleModel);
} else {
if ((!options || !options.allowInvalid) && !validateAfterResize) {
valids = validationResult.validFiles;
invalids = validationResult.invalidFiles;
} else {
valids = allNewFiles;
}
if (upload.attrGetter('ngfFixOrientation', attr, scope) && upload.isExifSupported()) {
applyExifRotations(valids, attr, scope).then(function () {
resizeAndUpdate();
});
} else {
resizeAndUpdate();
}
}
});
};
return upload;
}]);
ngFileUpload.directive('ngfSelect', ['$parse', '$timeout', '$compile', 'Upload', function ($parse, $timeout, $compile, Upload) {
var generatedElems = [];
function isDelayedClickSupported(ua) {
// fix for android native browser < 4.4 and safari windows
var m = ua.match(/Android[^\d]*(\d+)\.(\d+)/);
if (m && m.length > 2) {
var v = Upload.defaults.androidFixMinorVersion || 4;
return parseInt(m[1]) < 4 || (parseInt(m[1]) === v && parseInt(m[2]) < v);
}
// safari on windows
return ua.indexOf('Chrome') === -1 && /.*Windows.*Safari.*/.test(ua);
}
function linkFileSelect(scope, elem, attr, ngModel, $parse, $timeout, $compile, upload) {
/** @namespace attr.ngfSelect */
/** @namespace attr.ngfChange */
/** @namespace attr.ngModel */
/** @namespace attr.ngfModelOptions */
/** @namespace attr.ngfMultiple */
/** @namespace attr.ngfCapture */
/** @namespace attr.ngfValidate */
/** @namespace attr.ngfKeep */
var attrGetter = function (name, scope) {
return upload.attrGetter(name, attr, scope);
};
function isInputTypeFile() {
return elem[0].tagName.toLowerCase() === 'input' && attr.type && attr.type.toLowerCase() === 'file';
}
function fileChangeAttr() {
return attrGetter('ngfChange') || attrGetter('ngfSelect');
}
function changeFn(evt) {
if (upload.shouldUpdateOn('change', attr, scope)) {
var fileList = evt.__files_ || (evt.target && evt.target.files), files = [];
/* Handle duplicate call in IE11 */
if (!fileList) return;
for (var i = 0; i < fileList.length; i++) {
files.push(fileList[i]);
}
upload.updateModel(ngModel, attr, scope, fileChangeAttr(),
files.length ? files : null, evt);
}
}
upload.registerModelChangeValidator(ngModel, attr, scope);
var unwatches = [];
if (attrGetter('ngfMultiple')) {
unwatches.push(scope.$watch(attrGetter('ngfMultiple'), function () {
fileElem.attr('multiple', attrGetter('ngfMultiple', scope));
}));
}
if (attrGetter('ngfCapture')) {
unwatches.push(scope.$watch(attrGetter('ngfCapture'), function () {
fileElem.attr('capture', attrGetter('ngfCapture', scope));
}));
}
if (attrGetter('ngfAccept')) {
unwatches.push(scope.$watch(attrGetter('ngfAccept'), function () {
fileElem.attr('accept', attrGetter('ngfAccept', scope));
}));
}
unwatches.push(attr.$observe('accept', function () {
fileElem.attr('accept', attrGetter('accept'));
}));
function bindAttrToFileInput(fileElem, label) {
function updateId(val) {
fileElem.attr('id', 'ngf-' + val);
label.attr('id', 'ngf-label-' + val);
}
for (var i = 0; i < elem[0].attributes.length; i++) {
var attribute = elem[0].attributes[i];
if (attribute.name !== 'type' && attribute.name !== 'class' && attribute.name !== 'style') {
if (attribute.name === 'id') {
updateId(attribute.value);
unwatches.push(attr.$observe('id', updateId));
} else {
fileElem.attr(attribute.name, (!attribute.value && (attribute.name === 'required' ||
attribute.name === 'multiple')) ? attribute.name : attribute.value);
}
}
}
}
function createFileInput() {
if (isInputTypeFile()) {
return elem;
}
var fileElem = angular.element(' ');
var label = angular.element('upload ');
label.css('visibility', 'hidden').css('position', 'absolute').css('overflow', 'hidden')
.css('width', '0px').css('height', '0px').css('border', 'none')
.css('margin', '0px').css('padding', '0px').attr('tabindex', '-1');
bindAttrToFileInput(fileElem, label);
generatedElems.push({ el: elem, ref: label });
document.body.appendChild(label.append(fileElem)[0]);
return fileElem;
}
function clickHandler(evt) {
if (elem.attr('disabled')) return false;
if (attrGetter('ngfSelectDisabled', scope)) return;
var r = detectSwipe(evt);
// prevent the click if it is a swipe
if (r != null) return r;
resetModel(evt);
// fix for md when the element is removed from the DOM and added back #460
try {
if (!isInputTypeFile() && !document.body.contains(fileElem[0])) {
generatedElems.push({ el: elem, ref: fileElem.parent() });
document.body.appendChild(fileElem.parent()[0]);
fileElem.bind('change', changeFn);
}
} catch (e) {/*ignore*/
}
if (isDelayedClickSupported(navigator.userAgent)) {
setTimeout(function () {
fileElem[0].click();
}, 0);
} else {
fileElem[0].click();
}
return false;
}
var initialTouchStartY = 0;
var initialTouchStartX = 0;
function detectSwipe(evt) {
var touches = evt.changedTouches || (evt.originalEvent && evt.originalEvent.changedTouches);
if (touches) {
if (evt.type === 'touchstart') {
initialTouchStartX = touches[0].clientX;
initialTouchStartY = touches[0].clientY;
return true; // don't block event default
} else {
// prevent scroll from triggering event
if (evt.type === 'touchend') {
var currentX = touches[0].clientX;
var currentY = touches[0].clientY;
if ((Math.abs(currentX - initialTouchStartX) > 20) ||
(Math.abs(currentY - initialTouchStartY) > 20)) {
evt.stopPropagation();
evt.preventDefault();
return false;
}
}
return true;
}
}
}
var fileElem = elem;
function resetModel(evt) {
if (upload.shouldUpdateOn('click', attr, scope) && fileElem.val()) {
fileElem.val(null);
upload.updateModel(ngModel, attr, scope, fileChangeAttr(), null, evt, true);
}
}
if (!isInputTypeFile()) {
fileElem = createFileInput();
}
fileElem.bind('change', changeFn);
if (!isInputTypeFile()) {
elem.bind('click touchstart touchend', clickHandler);
} else {
elem.bind('click', resetModel);
}
function ie10SameFileSelectFix(evt) {
if (fileElem && !fileElem.attr('__ngf_ie10_Fix_')) {
if (!fileElem[0].parentNode) {
fileElem = null;
return;
}
evt.preventDefault();
evt.stopPropagation();
fileElem.unbind('click');
var clone = fileElem.clone();
fileElem.replaceWith(clone);
fileElem = clone;
fileElem.attr('__ngf_ie10_Fix_', 'true');
fileElem.bind('change', changeFn);
fileElem.bind('click', ie10SameFileSelectFix);
fileElem[0].click();
return false;
} else {
fileElem.removeAttr('__ngf_ie10_Fix_');
}
}
if (navigator.appVersion.indexOf('MSIE 10') !== -1) {
fileElem.bind('click', ie10SameFileSelectFix);
}
if (ngModel) ngModel.$formatters.push(function (val) {
if (val == null || val.length === 0) {
if (fileElem.val()) {
fileElem.val(null);
}
}
return val;
});
scope.$on('$destroy', function () {
if (!isInputTypeFile()) fileElem.parent().remove();
angular.forEach(unwatches, function (unwatch) {
unwatch();
});
});
$timeout(function () {
for (var i = 0; i < generatedElems.length; i++) {
var g = generatedElems[i];
if (!document.body.contains(g.el[0])) {
generatedElems.splice(i, 1);
g.ref.remove();
}
}
});
if (window.FileAPI && window.FileAPI.ngfFixIE) {
window.FileAPI.ngfFixIE(elem, fileElem, changeFn);
}
}
return {
restrict: 'AEC',
require: '?ngModel',
link: function (scope, elem, attr, ngModel) {
linkFileSelect(scope, elem, attr, ngModel, $parse, $timeout, $compile, Upload);
}
};
}]);
(function () {
ngFileUpload.service('UploadDataUrl', ['UploadBase', '$timeout', '$q', function (UploadBase, $timeout, $q) {
var upload = UploadBase;
upload.base64DataUrl = function (file) {
if (angular.isArray(file)) {
var d = $q.defer(), count = 0;
angular.forEach(file, function (f) {
upload.dataUrl(f, true)['finally'](function () {
count++;
if (count === file.length) {
var urls = [];
angular.forEach(file, function (ff) {
urls.push(ff.$ngfDataUrl);
});
d.resolve(urls, file);
}
});
});
return d.promise;
} else {
return upload.dataUrl(file, true);
}
};
upload.dataUrl = function (file, disallowObjectUrl) {
if (!file) return upload.emptyPromise(file, file);
if ((disallowObjectUrl && file.$ngfDataUrl != null) || (!disallowObjectUrl && file.$ngfBlobUrl != null)) {
return upload.emptyPromise(disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl, file);
}
var p = disallowObjectUrl ? file.$$ngfDataUrlPromise : file.$$ngfBlobUrlPromise;
if (p) return p;
var deferred = $q.defer();
$timeout(function () {
if (window.FileReader && file &&
(!window.FileAPI || navigator.userAgent.indexOf('MSIE 8') === -1 || file.size < 20000) &&
(!window.FileAPI || navigator.userAgent.indexOf('MSIE 9') === -1 || file.size < 4000000)) {
//prefer URL.createObjectURL for handling refrences to files of all sizes
//since it doesn´t build a large string in memory
var URL = window.URL || window.webkitURL;
if (URL && URL.createObjectURL && !disallowObjectUrl) {
var url;
try {
url = URL.createObjectURL(file);
} catch (e) {
$timeout(function () {
file.$ngfBlobUrl = '';
deferred.reject();
});
return;
}
$timeout(function () {
file.$ngfBlobUrl = url;
if (url) {
deferred.resolve(url, file);
upload.blobUrls = upload.blobUrls || [];
upload.blobUrlsTotalSize = upload.blobUrlsTotalSize || 0;
upload.blobUrls.push({ url: url, size: file.size });
upload.blobUrlsTotalSize += file.size || 0;
var maxMemory = upload.defaults.blobUrlsMaxMemory || 268435456;
var maxLength = upload.defaults.blobUrlsMaxQueueSize || 200;
while ((upload.blobUrlsTotalSize > maxMemory || upload.blobUrls.length > maxLength) && upload.blobUrls.length > 1) {
var obj = upload.blobUrls.splice(0, 1)[0];
URL.revokeObjectURL(obj.url);
upload.blobUrlsTotalSize -= obj.size;
}
}
});
} else {
var fileReader = new FileReader();
fileReader.onload = function (e) {
$timeout(function () {
file.$ngfDataUrl = e.target.result;
deferred.resolve(e.target.result, file);
$timeout(function () {
delete file.$ngfDataUrl;
}, 1000);
});
};
fileReader.onerror = function () {
$timeout(function () {
file.$ngfDataUrl = '';
deferred.reject();
});
};
fileReader.readAsDataURL(file);
}
} else {
$timeout(function () {
file[disallowObjectUrl ? '$ngfDataUrl' : '$ngfBlobUrl'] = '';
deferred.reject();
});
}
});
if (disallowObjectUrl) {
p = file.$$ngfDataUrlPromise = deferred.promise;
} else {
p = file.$$ngfBlobUrlPromise = deferred.promise;
}
p['finally'](function () {
delete file[disallowObjectUrl ? '$$ngfDataUrlPromise' : '$$ngfBlobUrlPromise'];
});
return p;
};
return upload;
}]);
function getTagType(el) {
if (el.tagName.toLowerCase() === 'img') return 'image';
if (el.tagName.toLowerCase() === 'audio') return 'audio';
if (el.tagName.toLowerCase() === 'video') return 'video';
return /./;
}
function linkFileDirective(Upload, $timeout, scope, elem, attr, directiveName, resizeParams, isBackground) {
function constructDataUrl(file) {
var disallowObjectUrl = Upload.attrGetter('ngfNoObjectUrl', attr, scope);
Upload.dataUrl(file, disallowObjectUrl)['finally'](function () {
$timeout(function () {
var src = (disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl) || file.$ngfDataUrl;
if (isBackground) {
elem.css('background-image', 'url(\'' + (src || '') + '\')');
} else {
elem.attr('src', src);
}
if (src) {
elem.removeClass('ng-hide');
} else {
elem.addClass('ng-hide');
}
});
});
}
$timeout(function () {
var unwatch = scope.$watch(attr[directiveName], function (file) {
var size = resizeParams;
if (directiveName === 'ngfThumbnail') {
if (!size) {
size = {
width: elem[0].naturalWidth || elem[0].clientWidth,
height: elem[0].naturalHeight || elem[0].clientHeight
};
}
if (size.width === 0 && window.getComputedStyle) {
var style = getComputedStyle(elem[0]);
if (style.width && style.width.indexOf('px') > -1 && style.height && style.height.indexOf('px') > -1) {
size = {
width: parseInt(style.width.slice(0, -2)),
height: parseInt(style.height.slice(0, -2))
};
}
}
}
if (angular.isString(file)) {
elem.removeClass('ng-hide');
if (isBackground) {
return elem.css('background-image', 'url(\'' + file + '\')');
} else {
return elem.attr('src', file);
}
}
if (file && file.type && file.type.search(getTagType(elem[0])) === 0 &&
(!isBackground || file.type.indexOf('image') === 0)) {
if (size && Upload.isResizeSupported()) {
size.resizeIf = function (width, height) {
return Upload.attrGetter('ngfResizeIf', attr, scope,
{ $width: width, $height: height, $file: file });
};
Upload.resize(file, size).then(
function (f) {
constructDataUrl(f);
}, function (e) {
throw e;
}
);
} else {
constructDataUrl(file);
}
} else {
elem.addClass('ng-hide');
}
});
scope.$on('$destroy', function () {
unwatch();
});
});
}
/** @namespace attr.ngfSrc */
/** @namespace attr.ngfNoObjectUrl */
ngFileUpload.directive('ngfSrc', ['Upload', '$timeout', function (Upload, $timeout) {
return {
restrict: 'AE',
link: function (scope, elem, attr) {
linkFileDirective(Upload, $timeout, scope, elem, attr, 'ngfSrc',
Upload.attrGetter('ngfResize', attr, scope), false);
}
};
}]);
/** @namespace attr.ngfBackground */
/** @namespace attr.ngfNoObjectUrl */
ngFileUpload.directive('ngfBackground', ['Upload', '$timeout', function (Upload, $timeout) {
return {
restrict: 'AE',
link: function (scope, elem, attr) {
linkFileDirective(Upload, $timeout, scope, elem, attr, 'ngfBackground',
Upload.attrGetter('ngfResize', attr, scope), true);
}
};
}]);
/** @namespace attr.ngfThumbnail */
/** @namespace attr.ngfAsBackground */
/** @namespace attr.ngfSize */
/** @namespace attr.ngfNoObjectUrl */
ngFileUpload.directive('ngfThumbnail', ['Upload', '$timeout', function (Upload, $timeout) {
return {
restrict: 'AE',
link: function (scope, elem, attr) {
var size = Upload.attrGetter('ngfSize', attr, scope);
linkFileDirective(Upload, $timeout, scope, elem, attr, 'ngfThumbnail', size,
Upload.attrGetter('ngfAsBackground', attr, scope));
}
};
}]);
ngFileUpload.config(['$compileProvider', function ($compileProvider) {
if ($compileProvider.imgSrcSanitizationWhitelist) $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|webcal|local|file|data|blob):/);
if ($compileProvider.aHrefSanitizationWhitelist) $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|webcal|local|file|data|blob):/);
}]);
ngFileUpload.filter('ngfDataUrl', ['UploadDataUrl', '$sce', function (UploadDataUrl, $sce) {
return function (file, disallowObjectUrl, trustedUrl) {
if (angular.isString(file)) {
return $sce.trustAsResourceUrl(file);
}
var src = file && ((disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl) || file.$ngfDataUrl);
if (file && !src) {
if (!file.$ngfDataUrlFilterInProgress && angular.isObject(file)) {
file.$ngfDataUrlFilterInProgress = true;
UploadDataUrl.dataUrl(file, disallowObjectUrl);
}
return '';
}
if (file) delete file.$ngfDataUrlFilterInProgress;
return (file && src ? (trustedUrl ? $sce.trustAsResourceUrl(src) : src) : file) || '';
};
}]);
})();
ngFileUpload.service('UploadValidate', ['UploadDataUrl', '$q', '$timeout', function (UploadDataUrl, $q, $timeout) {
var upload = UploadDataUrl;
function globStringToRegex(str) {
var regexp = '', excludes = [];
if (str.length > 2 && str[0] === '/' && str[str.length - 1] === '/') {
regexp = str.substring(1, str.length - 1);
} else {
var split = str.split(',');
if (split.length > 1) {
for (var i = 0; i < split.length; i++) {
var r = globStringToRegex(split[i]);
if (r.regexp) {
regexp += '(' + r.regexp + ')';
if (i < split.length - 1) {
regexp += '|';
}
} else {
excludes = excludes.concat(r.excludes);
}
}
} else {
if (str.indexOf('!') === 0) {
excludes.push('^((?!' + globStringToRegex(str.substring(1)).regexp + ').)*$');
} else {
if (str.indexOf('.') === 0) {
str = '*' + str;
}
regexp = '^' + str.replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\-]', 'g'), '\\$&') + '$';
regexp = regexp.replace(/\\\*/g, '.*').replace(/\\\?/g, '.');
}
}
}
return { regexp: regexp, excludes: excludes };
}
upload.validatePattern = function (file, val) {
if (!val) {
return true;
}
var pattern = globStringToRegex(val), valid = true;
if (pattern.regexp && pattern.regexp.length) {
var regexp = new RegExp(pattern.regexp, 'i');
valid = (file.type != null && regexp.test(file.type)) ||
(file.name != null && regexp.test(file.name));
}
var len = pattern.excludes.length;
while (len--) {
var exclude = new RegExp(pattern.excludes[len], 'i');
valid = valid && (file.type == null || exclude.test(file.type)) &&
(file.name == null || exclude.test(file.name));
}
return valid;
};
upload.ratioToFloat = function (val) {
var r = val.toString(), xIndex = r.search(/[x:]/i);
if (xIndex > -1) {
r = parseFloat(r.substring(0, xIndex)) / parseFloat(r.substring(xIndex + 1));
} else {
r = parseFloat(r);
}
return r;
};
upload.registerModelChangeValidator = function (ngModel, attr, scope) {
if (ngModel) {
ngModel.$formatters.push(function (files) {
if (ngModel.$dirty) {
var filesArray = files;
if (files && !angular.isArray(files)) {
filesArray = [files];
}
upload.validate(filesArray, 0, ngModel, attr, scope).then(function () {
upload.applyModelValidation(ngModel, filesArray);
});
}
return files;
});
}
};
function markModelAsDirty(ngModel, files) {
if (files != null && !ngModel.$dirty) {
if (ngModel.$setDirty) {
ngModel.$setDirty();
} else {
ngModel.$dirty = true;
}
}
}
upload.applyModelValidation = function (ngModel, files) {
markModelAsDirty(ngModel, files);
angular.forEach(ngModel.$ngfValidations, function (validation) {
ngModel.$setValidity(validation.name, validation.valid);
});
};
upload.getValidationAttr = function (attr, scope, name, validationName, file) {
var dName = 'ngf' + name[0].toUpperCase() + name.substr(1);
var val = upload.attrGetter(dName, attr, scope, { $file: file });
if (val == null) {
val = upload.attrGetter('ngfValidate', attr, scope, { $file: file });
if (val) {
var split = (validationName || name).split('.');
val = val[split[0]];
if (split.length > 1) {
val = val && val[split[1]];
}
}
}
return val;
};
upload.validate = function (files, prevLength, ngModel, attr, scope) {
ngModel = ngModel || {};
ngModel.$ngfValidations = ngModel.$ngfValidations || [];
angular.forEach(ngModel.$ngfValidations, function (v) {
v.valid = true;
});
var attrGetter = function (name, params) {
return upload.attrGetter(name, attr, scope, params);
};
var ignoredErrors = (upload.attrGetter('ngfIgnoreInvalid', attr, scope) || '').split(' ');
var runAllValidation = upload.attrGetter('ngfRunAllValidations', attr, scope);
if (files == null || files.length === 0) {
return upload.emptyPromise({ 'validFiles': files, 'invalidFiles': [] });
}
files = files.length === undefined ? [files] : files.slice(0);
var invalidFiles = [];
function validateSync(name, validationName, fn) {
if (files) {
var i = files.length, valid = null;
while (i--) {
var file = files[i];
if (file) {
var val = upload.getValidationAttr(attr, scope, name, validationName, file);
if (val != null) {
if (!fn(file, val, i)) {
if (ignoredErrors.indexOf(name) === -1) {
file.$error = name;
(file.$errorMessages = (file.$errorMessages || {}))[name] = true;
file.$errorParam = val;
if (invalidFiles.indexOf(file) === -1) {
invalidFiles.push(file);
}
if (!runAllValidation) {
files.splice(i, 1);
}
valid = false;
} else {
files.splice(i, 1);
}
}
}
}
}
if (valid !== null) {
ngModel.$ngfValidations.push({ name: name, valid: valid });
}
}
}
validateSync('pattern', null, upload.validatePattern);
validateSync('minSize', 'size.min', function (file, val) {
return file.size + 0.1 >= upload.translateScalars(val);
});
validateSync('maxSize', 'size.max', function (file, val) {
return file.size - 0.1 <= upload.translateScalars(val);
});
var totalSize = 0;
validateSync('maxTotalSize', null, function (file, val) {
totalSize += file.size;
if (totalSize > upload.translateScalars(val)) {
files.splice(0, files.length);
return false;
}
return true;
});
validateSync('validateFn', null, function (file, r) {
return r === true || r === null || r === '';
});
if (!files.length) {
return upload.emptyPromise({ 'validFiles': [], 'invalidFiles': invalidFiles });
}
function validateAsync(name, validationName, type, asyncFn, fn) {
function resolveResult(defer, file, val) {
function resolveInternal(fn) {
if (fn()) {
if (ignoredErrors.indexOf(name) === -1) {
file.$error = name;
(file.$errorMessages = (file.$errorMessages || {}))[name] = true;
file.$errorParam = val;
if (invalidFiles.indexOf(file) === -1) {
invalidFiles.push(file);
}
if (!runAllValidation) {
var i = files.indexOf(file);
if (i > -1) files.splice(i, 1);
}
defer.resolve(false);
} else {
var j = files.indexOf(file);
if (j > -1) files.splice(j, 1);
defer.resolve(true);
}
} else {
defer.resolve(true);
}
}
if (val != null) {
asyncFn(file, val).then(function (d) {
resolveInternal(function () {
return !fn(d, val);
});
}, function () {
resolveInternal(function () {
return attrGetter('ngfValidateForce', { $file: file });
});
});
} else {
defer.resolve(true);
}
}
var promises = [upload.emptyPromise(true)];
if (files) {
files = files.length === undefined ? [files] : files;
angular.forEach(files, function (file) {
var defer = $q.defer();
promises.push(defer.promise);
if (type && (file.type == null || file.type.search(type) !== 0)) {
defer.resolve(true);
return;
}
if (name === 'dimensions' && upload.attrGetter('ngfDimensions', attr) != null) {
upload.imageDimensions(file).then(function (d) {
resolveResult(defer, file,
attrGetter('ngfDimensions', { $file: file, $width: d.width, $height: d.height }));
}, function () {
defer.resolve(false);
});
} else if (name === 'duration' && upload.attrGetter('ngfDuration', attr) != null) {
upload.mediaDuration(file).then(function (d) {
resolveResult(defer, file,
attrGetter('ngfDuration', { $file: file, $duration: d }));
}, function () {
defer.resolve(false);
});
} else {
resolveResult(defer, file,
upload.getValidationAttr(attr, scope, name, validationName, file));
}
});
}
var deffer = $q.defer();
$q.all(promises).then(function (values) {
var isValid = true;
for (var i = 0; i < values.length; i++) {
if (!values[i]) {
isValid = false;
break;
}
}
ngModel.$ngfValidations.push({ name: name, valid: isValid });
deffer.resolve(isValid);
});
return deffer.promise;
}
var deffer = $q.defer();
var promises = [];
promises.push(validateAsync('maxHeight', 'height.max', /image/,
this.imageDimensions, function (d, val) {
return d.height <= val;
}));
promises.push(validateAsync('minHeight', 'height.min', /image/,
this.imageDimensions, function (d, val) {
return d.height >= val;
}));
promises.push(validateAsync('maxWidth', 'width.max', /image/,
this.imageDimensions, function (d, val) {
return d.width <= val;
}));
promises.push(validateAsync('minWidth', 'width.min', /image/,
this.imageDimensions, function (d, val) {
return d.width >= val;
}));
promises.push(validateAsync('dimensions', null, /image/,
function (file, val) {
return upload.emptyPromise(val);
}, function (r) {
return r;
}));
promises.push(validateAsync('ratio', null, /image/,
this.imageDimensions, function (d, val) {
var split = val.toString().split(','), valid = false;
for (var i = 0; i < split.length; i++) {
if (Math.abs((d.width / d.height) - upload.ratioToFloat(split[i])) < 0.01) {
valid = true;
}
}
return valid;
}));
promises.push(validateAsync('maxRatio', 'ratio.max', /image/,
this.imageDimensions, function (d, val) {
return (d.width / d.height) - upload.ratioToFloat(val) < 0.0001;
}));
promises.push(validateAsync('minRatio', 'ratio.min', /image/,
this.imageDimensions, function (d, val) {
return (d.width / d.height) - upload.ratioToFloat(val) > -0.0001;
}));
promises.push(validateAsync('maxDuration', 'duration.max', /audio|video/,
this.mediaDuration, function (d, val) {
return d <= upload.translateScalars(val);
}));
promises.push(validateAsync('minDuration', 'duration.min', /audio|video/,
this.mediaDuration, function (d, val) {
return d >= upload.translateScalars(val);
}));
promises.push(validateAsync('duration', null, /audio|video/,
function (file, val) {
return upload.emptyPromise(val);
}, function (r) {
return r;
}));
promises.push(validateAsync('validateAsyncFn', null, null,
function (file, val) {
return val;
}, function (r) {
return r === true || r === null || r === '';
}));
$q.all(promises).then(function () {
if (runAllValidation) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (file.$error) {
files.splice(i--, 1);
}
}
}
runAllValidation = false;
validateSync('maxFiles', null, function (file, val, i) {
return prevLength + i < val;
});
deffer.resolve({ 'validFiles': files, 'invalidFiles': invalidFiles });
});
return deffer.promise;
};
upload.imageDimensions = function (file) {
if (file.$ngfWidth && file.$ngfHeight) {
var d = $q.defer();
$timeout(function () {
d.resolve({ width: file.$ngfWidth, height: file.$ngfHeight });
});
return d.promise;
}
if (file.$ngfDimensionPromise) return file.$ngfDimensionPromise;
var deferred = $q.defer();
$timeout(function () {
if (file.type.indexOf('image') !== 0) {
deferred.reject('not image');
return;
}
upload.dataUrl(file).then(function (dataUrl) {
var img = angular.element(' ').attr('src', dataUrl)
.css('visibility', 'hidden').css('position', 'fixed')
.css('max-width', 'none !important').css('max-height', 'none !important');
function success() {
var width = img[0].naturalWidth || img[0].clientWidth;
var height = img[0].naturalHeight || img[0].clientHeight;
img.remove();
file.$ngfWidth = width;
file.$ngfHeight = height;
deferred.resolve({ width: width, height: height });
}
function error() {
img.remove();
deferred.reject('load error');
}
img.on('load', success);
img.on('error', error);
var secondsCounter = 0;
function checkLoadErrorInCaseOfNoCallback() {
$timeout(function () {
if (img[0].parentNode) {
if (img[0].clientWidth) {
success();
} else if (secondsCounter++ > 10) {
error();
} else {
checkLoadErrorInCaseOfNoCallback();
}
}
}, 1000);
}
checkLoadErrorInCaseOfNoCallback();
angular.element(document.getElementsByTagName('body')[0]).append(img);
}, function () {
deferred.reject('load error');
});
});
file.$ngfDimensionPromise = deferred.promise;
file.$ngfDimensionPromise['finally'](function () {
delete file.$ngfDimensionPromise;
});
return file.$ngfDimensionPromise;
};
upload.mediaDuration = function (file) {
if (file.$ngfDuration) {
var d = $q.defer();
$timeout(function () {
d.resolve(file.$ngfDuration);
});
return d.promise;
}
if (file.$ngfDurationPromise) return file.$ngfDurationPromise;
var deferred = $q.defer();
$timeout(function () {
if (file.type.indexOf('audio') !== 0 && file.type.indexOf('video') !== 0) {
deferred.reject('not media');
return;
}
upload.dataUrl(file).then(function (dataUrl) {
var el = angular.element(file.type.indexOf('audio') === 0 ? '' : '')
.attr('src', dataUrl).css('visibility', 'none').css('position', 'fixed');
function success() {
var duration = el[0].duration;
file.$ngfDuration = duration;
el.remove();
deferred.resolve(duration);
}
function error() {
el.remove();
deferred.reject('load error');
}
el.on('loadedmetadata', success);
el.on('error', error);
var count = 0;
function checkLoadError() {
$timeout(function () {
if (el[0].parentNode) {
if (el[0].duration) {
success();
} else if (count > 10) {
error();
} else {
checkLoadError();
}
}
}, 1000);
}
checkLoadError();
angular.element(document.body).append(el);
}, function () {
deferred.reject('load error');
});
});
file.$ngfDurationPromise = deferred.promise;
file.$ngfDurationPromise['finally'](function () {
delete file.$ngfDurationPromise;
});
return file.$ngfDurationPromise;
};
return upload;
}
]);
ngFileUpload.service('UploadResize', ['UploadValidate', '$q', function (UploadValidate, $q) {
var upload = UploadValidate;
/**
* Conserve aspect ratio of the original region. Useful when shrinking/enlarging
* images to fit into a certain area.
* Source: http://stackoverflow.com/a/14731922
*
* @param {Number} srcWidth Source area width
* @param {Number} srcHeight Source area height
* @param {Number} maxWidth Nestable area maximum available width
* @param {Number} maxHeight Nestable area maximum available height
* @return {Object} { width, height }
*/
var calculateAspectRatioFit = function (srcWidth, srcHeight, maxWidth, maxHeight, centerCrop) {
var ratio = centerCrop ? Math.max(maxWidth / srcWidth, maxHeight / srcHeight) :
Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
return {
width: srcWidth * ratio, height: srcHeight * ratio,
marginX: srcWidth * ratio - maxWidth, marginY: srcHeight * ratio - maxHeight
};
};
// Extracted from https://github.com/romelgomez/angular-firebase-image-upload/blob/master/app/scripts/fileUpload.js#L89
var resize = function (imagen, width, height, quality, type, ratio, centerCrop, resizeIf) {
var deferred = $q.defer();
var canvasElement = document.createElement('canvas');
var imageElement = document.createElement('img');
imageElement.setAttribute('style', 'visibility:hidden;position:fixed;z-index:-100000');
document.body.appendChild(imageElement);
imageElement.onload = function () {
var imgWidth = imageElement.width, imgHeight = imageElement.height;
imageElement.parentNode.removeChild(imageElement);
if (resizeIf != null && resizeIf(imgWidth, imgHeight) === false) {
deferred.reject('resizeIf');
return;
}
try {
if (ratio) {
var ratioFloat = upload.ratioToFloat(ratio);
var imgRatio = imgWidth / imgHeight;
if (imgRatio < ratioFloat) {
width = imgWidth;
height = width / ratioFloat;
} else {
height = imgHeight;
width = height * ratioFloat;
}
}
if (!width) {
width = imgWidth;
}
if (!height) {
height = imgHeight;
}
var dimensions = calculateAspectRatioFit(imgWidth, imgHeight, width, height, centerCrop);
canvasElement.width = Math.min(dimensions.width, width);
canvasElement.height = Math.min(dimensions.height, height);
var context = canvasElement.getContext('2d');
context.drawImage(imageElement,
Math.min(0, -dimensions.marginX / 2), Math.min(0, -dimensions.marginY / 2),
dimensions.width, dimensions.height);
deferred.resolve(canvasElement.toDataURL(type || 'image/WebP', quality || 0.934));
} catch (e) {
deferred.reject(e);
}
};
imageElement.onerror = function () {
imageElement.parentNode.removeChild(imageElement);
deferred.reject();
};
imageElement.src = imagen;
return deferred.promise;
};
upload.dataUrltoBlob = function (dataurl, name, origSize) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
var blob = new window.Blob([u8arr], { type: mime });
blob.name = name;
blob.$ngfOrigSize = origSize;
return blob;
};
upload.isResizeSupported = function () {
var elem = document.createElement('canvas');
return window.atob && elem.getContext && elem.getContext('2d') && window.Blob;
};
if (upload.isResizeSupported()) {
// add name getter to the blob constructor prototype
Object.defineProperty(window.Blob.prototype, 'name', {
get: function () {
return this.$ngfName;
},
set: function (v) {
this.$ngfName = v;
},
configurable: true
});
}
upload.resize = function (file, options) {
if (file.type.indexOf('image') !== 0) return upload.emptyPromise(file);
var deferred = $q.defer();
upload.dataUrl(file, true).then(function (url) {
resize(url, options.width, options.height, options.quality, options.type || file.type,
options.ratio, options.centerCrop, options.resizeIf)
.then(function (dataUrl) {
if (file.type === 'image/jpeg' && options.restoreExif !== false) {
try {
dataUrl = upload.restoreExif(url, dataUrl);
} catch (e) {
setTimeout(function () { throw e; }, 1);
}
}
try {
var blob = upload.dataUrltoBlob(dataUrl, file.name, file.size);
deferred.resolve(blob);
} catch (e) {
deferred.reject(e);
}
}, function (r) {
if (r === 'resizeIf') {
deferred.resolve(file);
}
deferred.reject(r);
});
}, function (e) {
deferred.reject(e);
});
return deferred.promise;
};
return upload;
}]);
(function () {
ngFileUpload.directive('ngfDrop', ['$parse', '$timeout', '$window', 'Upload', '$http', '$q',
function ($parse, $timeout, $window, Upload, $http, $q) {
return {
restrict: 'AEC',
require: '?ngModel',
link: function (scope, elem, attr, ngModel) {
linkDrop(scope, elem, attr, ngModel, $parse, $timeout, $window, Upload, $http, $q);
}
};
}]);
ngFileUpload.directive('ngfNoFileDrop', function () {
return function (scope, elem) {
if (dropAvailable()) elem.css('display', 'none');
};
});
ngFileUpload.directive('ngfDropAvailable', ['$parse', '$timeout', 'Upload', function ($parse, $timeout, Upload) {
return function (scope, elem, attr) {
if (dropAvailable()) {
var model = $parse(Upload.attrGetter('ngfDropAvailable', attr));
$timeout(function () {
model(scope);
if (model.assign) {
model.assign(scope, true);
}
});
}
};
}]);
function linkDrop(scope, elem, attr, ngModel, $parse, $timeout, $window, upload, $http, $q) {
var available = dropAvailable();
var attrGetter = function (name, scope, params) {
return upload.attrGetter(name, attr, scope, params);
};
if (attrGetter('dropAvailable')) {
$timeout(function () {
if (scope[attrGetter('dropAvailable')]) {
scope[attrGetter('dropAvailable')].value = available;
} else {
scope[attrGetter('dropAvailable')] = available;
}
});
}
if (!available) {
if (attrGetter('ngfHideOnDropNotAvailable', scope) === true) {
elem.css('display', 'none');
}
return;
}
function isDisabled() {
return elem.attr('disabled') || attrGetter('ngfDropDisabled', scope);
}
if (attrGetter('ngfSelect') == null) {
upload.registerModelChangeValidator(ngModel, attr, scope);
}
var leaveTimeout = null;
var stopPropagation = $parse(attrGetter('ngfStopPropagation'));
var dragOverDelay = 1;
var actualDragOverClass;
elem[0].addEventListener('dragover', function (evt) {
if (isDisabled() || !upload.shouldUpdateOn('drop', attr, scope)) return;
evt.preventDefault();
if (stopPropagation(scope)) evt.stopPropagation();
// handling dragover events from the Chrome download bar
if (navigator.userAgent.indexOf('Chrome') > -1) {
var b = evt.dataTransfer.effectAllowed;
evt.dataTransfer.dropEffect = ('move' === b || 'linkMove' === b) ? 'move' : 'copy';
}
$timeout.cancel(leaveTimeout);
if (!actualDragOverClass) {
actualDragOverClass = 'C';
calculateDragOverClass(scope, attr, evt, function (clazz) {
actualDragOverClass = clazz;
elem.addClass(actualDragOverClass);
attrGetter('ngfDrag', scope, { $isDragging: true, $class: actualDragOverClass, $event: evt });
});
}
}, false);
elem[0].addEventListener('dragenter', function (evt) {
if (isDisabled() || !upload.shouldUpdateOn('drop', attr, scope)) return;
evt.preventDefault();
if (stopPropagation(scope)) evt.stopPropagation();
}, false);
elem[0].addEventListener('dragleave', function (evt) {
if (isDisabled() || !upload.shouldUpdateOn('drop', attr, scope)) return;
evt.preventDefault();
if (stopPropagation(scope)) evt.stopPropagation();
leaveTimeout = $timeout(function () {
if (actualDragOverClass) elem.removeClass(actualDragOverClass);
actualDragOverClass = null;
attrGetter('ngfDrag', scope, { $isDragging: false, $event: evt });
}, dragOverDelay || 100);
}, false);
elem[0].addEventListener('drop', function (evt) {
if (isDisabled() || !upload.shouldUpdateOn('drop', attr, scope)) return;
evt.preventDefault();
if (stopPropagation(scope)) evt.stopPropagation();
if (actualDragOverClass) elem.removeClass(actualDragOverClass);
actualDragOverClass = null;
extractFilesAndUpdateModel(evt.dataTransfer, evt, 'dropUrl');
}, false);
elem[0].addEventListener('paste', function (evt) {
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1 &&
attrGetter('ngfEnableFirefoxPaste', scope)) {
evt.preventDefault();
}
if (isDisabled() || !upload.shouldUpdateOn('paste', attr, scope)) return;
extractFilesAndUpdateModel(evt.clipboardData || evt.originalEvent.clipboardData, evt, 'pasteUrl');
}, false);
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1 &&
attrGetter('ngfEnableFirefoxPaste', scope)) {
elem.attr('contenteditable', true);
elem.on('keypress', function (e) {
if (!e.metaKey && !e.ctrlKey) {
e.preventDefault();
}
});
}
function extractFilesAndUpdateModel(source, evt, updateOnType) {
if (!source) return;
// html needs to be calculated on the same process otherwise the data will be wiped
// after promise resolve or setTimeout.
var html;
try {
html = source && source.getData && source.getData('text/html');
} catch (e) {/* Fix IE11 that throw error calling getData */
}
extractFiles(source.items, source.files, attrGetter('ngfAllowDir', scope) !== false,
attrGetter('multiple') || attrGetter('ngfMultiple', scope)).then(function (files) {
if (files.length) {
updateModel(files, evt);
} else {
extractFilesFromHtml(updateOnType, html).then(function (files) {
updateModel(files, evt);
});
}
});
}
function updateModel(files, evt) {
upload.updateModel(ngModel, attr, scope, attrGetter('ngfChange') || attrGetter('ngfDrop'), files, evt);
}
function extractFilesFromHtml(updateOn, html) {
if (!upload.shouldUpdateOn(updateOn, attr, scope) || typeof html !== 'string') return upload.rejectPromise([]);
var urls = [];
html.replace(/<(img src|img [^>]* src) *=\"([^\"]*)\"/gi, function (m, n, src) {
urls.push(src);
});
var promises = [], files = [];
if (urls.length) {
angular.forEach(urls, function (url) {
promises.push(upload.urlToBlob(url).then(function (blob) {
files.push(blob);
}));
});
var defer = $q.defer();
$q.all(promises).then(function () {
defer.resolve(files);
}, function (e) {
defer.reject(e);
});
return defer.promise;
}
return upload.emptyPromise();
}
function calculateDragOverClass(scope, attr, evt, callback) {
var obj = attrGetter('ngfDragOverClass', scope, { $event: evt }), dClass = 'dragover';
if (angular.isString(obj)) {
dClass = obj;
} else if (obj) {
if (obj.delay) dragOverDelay = obj.delay;
if (obj.accept || obj.reject) {
var items = evt.dataTransfer.items;
if (items == null || !items.length) {
dClass = obj.accept;
} else {
var pattern = obj.pattern || attrGetter('ngfPattern', scope, { $event: evt });
var len = items.length;
while (len--) {
if (!upload.validatePattern(items[len], pattern)) {
dClass = obj.reject;
break;
} else {
dClass = obj.accept;
}
}
}
}
}
callback(dClass);
}
function extractFiles(items, fileList, allowDir, multiple) {
var maxFiles = upload.getValidationAttr(attr, scope, 'maxFiles');
if (maxFiles == null) {
maxFiles = Number.MAX_VALUE;
}
var maxTotalSize = upload.getValidationAttr(attr, scope, 'maxTotalSize');
if (maxTotalSize == null) {
maxTotalSize = Number.MAX_VALUE;
}
var includeDir = attrGetter('ngfIncludeDir', scope);
var files = [], totalSize = 0;
function traverseFileTree(entry, path) {
var defer = $q.defer();
if (entry != null) {
if (entry.isDirectory) {
var promises = [upload.emptyPromise()];
if (includeDir) {
var file = { type: 'directory' };
file.name = file.path = (path || '') + entry.name;
files.push(file);
}
var dirReader = entry.createReader();
var entries = [];
var readEntries = function () {
dirReader.readEntries(function (results) {
try {
if (!results.length) {
angular.forEach(entries.slice(0), function (e) {
if (files.length <= maxFiles && totalSize <= maxTotalSize) {
promises.push(traverseFileTree(e, (path ? path : '') + entry.name + '/'));
}
});
$q.all(promises).then(function () {
defer.resolve();
}, function (e) {
defer.reject(e);
});
} else {
entries = entries.concat(Array.prototype.slice.call(results || [], 0));
readEntries();
}
} catch (e) {
defer.reject(e);
}
}, function (e) {
defer.reject(e);
});
};
readEntries();
} else {
entry.file(function (file) {
try {
file.path = (path ? path : '') + file.name;
if (includeDir) {
file = upload.rename(file, file.path);
}
files.push(file);
totalSize += file.size;
defer.resolve();
} catch (e) {
defer.reject(e);
}
}, function (e) {
defer.reject(e);
});
}
}
return defer.promise;
}
var promises = [upload.emptyPromise()];
if (items && items.length > 0 && $window.location.protocol !== 'file:') {
for (var i = 0; i < items.length; i++) {
if (items[i].webkitGetAsEntry && items[i].webkitGetAsEntry() && items[i].webkitGetAsEntry().isDirectory) {
var entry = items[i].webkitGetAsEntry();
if (entry.isDirectory && !allowDir) {
continue;
}
if (entry != null) {
promises.push(traverseFileTree(entry));
}
} else {
var f = items[i].getAsFile();
if (f != null) {
files.push(f);
totalSize += f.size;
}
}
if (files.length > maxFiles || totalSize > maxTotalSize ||
(!multiple && files.length > 0)) break;
}
} else {
if (fileList != null) {
for (var j = 0; j < fileList.length; j++) {
var file = fileList.item(j);
if (file.type || file.size > 0) {
files.push(file);
totalSize += file.size;
}
if (files.length > maxFiles || totalSize > maxTotalSize ||
(!multiple && files.length > 0)) break;
}
}
}
var defer = $q.defer();
$q.all(promises).then(function () {
if (!multiple && !includeDir && files.length) {
var i = 0;
while (files[i] && files[i].type === 'directory') i++;
defer.resolve([files[i]]);
} else {
defer.resolve(files);
}
}, function (e) {
defer.reject(e);
});
return defer.promise;
}
}
function dropAvailable() {
var div = document.createElement('div');
return ('draggable' in div) && ('ondrop' in div) && !/Edge\/12./i.test(navigator.userAgent);
}
})();
// customized version of https://github.com/exif-js/exif-js
ngFileUpload.service('UploadExif', ['UploadResize', '$q', function (UploadResize, $q) {
var upload = UploadResize;
upload.isExifSupported = function () {
return window.FileReader && new FileReader().readAsArrayBuffer && upload.isResizeSupported();
};
function applyTransform(ctx, orientation, width, height) {
switch (orientation) {
case 2:
return ctx.transform(-1, 0, 0, 1, width, 0);
case 3:
return ctx.transform(-1, 0, 0, -1, width, height);
case 4:
return ctx.transform(1, 0, 0, -1, 0, height);
case 5:
return ctx.transform(0, 1, 1, 0, 0, 0);
case 6:
return ctx.transform(0, 1, -1, 0, height, 0);
case 7:
return ctx.transform(0, -1, -1, 0, height, width);
case 8:
return ctx.transform(0, -1, 1, 0, 0, width);
}
}
upload.readOrientation = function (file) {
var defer = $q.defer();
var reader = new FileReader();
var slicedFile = file.slice ? file.slice(0, 64 * 1024) : file;
reader.readAsArrayBuffer(slicedFile);
reader.onerror = function (e) {
return defer.reject(e);
};
reader.onload = function (e) {
var result = { orientation: 1 };
var view = new DataView(this.result);
if (view.getUint16(0, false) !== 0xFFD8) return defer.resolve(result);
var length = view.byteLength,
offset = 2;
while (offset < length) {
var marker = view.getUint16(offset, false);
offset += 2;
if (marker === 0xFFE1) {
if (view.getUint32(offset += 2, false) !== 0x45786966) return defer.resolve(result);
var little = view.getUint16(offset += 6, false) === 0x4949;
offset += view.getUint32(offset + 4, little);
var tags = view.getUint16(offset, little);
offset += 2;
for (var i = 0; i < tags; i++)
if (view.getUint16(offset + (i * 12), little) === 0x0112) {
var orientation = view.getUint16(offset + (i * 12) + 8, little);
if (orientation >= 2 && orientation <= 8) {
view.setUint16(offset + (i * 12) + 8, 1, little);
result.fixedArrayBuffer = e.target.result;
}
result.orientation = orientation;
return defer.resolve(result);
}
} else if ((marker & 0xFF00) !== 0xFF00) break;
else offset += view.getUint16(offset, false);
}
return defer.resolve(result);
};
return defer.promise;
};
function arrayBufferToBase64(buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
upload.applyExifRotation = function (file) {
if (file.type.indexOf('image/jpeg') !== 0) {
return upload.emptyPromise(file);
}
var deferred = $q.defer();
upload.readOrientation(file).then(function (result) {
if (result.orientation < 2 || result.orientation > 8) {
return deferred.resolve(file);
}
upload.dataUrl(file, true).then(function (url) {
var canvas = document.createElement('canvas');
var img = document.createElement('img');
img.onload = function () {
try {
canvas.width = result.orientation > 4 ? img.height : img.width;
canvas.height = result.orientation > 4 ? img.width : img.height;
var ctx = canvas.getContext('2d');
applyTransform(ctx, result.orientation, img.width, img.height);
ctx.drawImage(img, 0, 0);
var dataUrl = canvas.toDataURL(file.type || 'image/WebP', 0.934);
dataUrl = upload.restoreExif(arrayBufferToBase64(result.fixedArrayBuffer), dataUrl);
var blob = upload.dataUrltoBlob(dataUrl, file.name);
deferred.resolve(blob);
} catch (e) {
return deferred.reject(e);
}
};
img.onerror = function () {
deferred.reject();
};
img.src = url;
}, function (e) {
deferred.reject(e);
});
}, function (e) {
deferred.reject(e);
});
return deferred.promise;
};
upload.restoreExif = function (orig, resized) {
var ExifRestorer = {};
ExifRestorer.KEY_STR = 'ABCDEFGHIJKLMNOP' +
'QRSTUVWXYZabcdef' +
'ghijklmnopqrstuv' +
'wxyz0123456789+/' +
'=';
ExifRestorer.encode64 = function (input) {
var output = '',
chr1, chr2, chr3 = '',
enc1, enc2, enc3, enc4 = '',
i = 0;
do {
chr1 = input[i++];
chr2 = input[i++];
chr3 = input[i++];
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this.KEY_STR.charAt(enc1) +
this.KEY_STR.charAt(enc2) +
this.KEY_STR.charAt(enc3) +
this.KEY_STR.charAt(enc4);
chr1 = chr2 = chr3 = '';
enc1 = enc2 = enc3 = enc4 = '';
} while (i < input.length);
return output;
};
ExifRestorer.restore = function (origFileBase64, resizedFileBase64) {
if (origFileBase64.match('data:image/jpeg;base64,')) {
origFileBase64 = origFileBase64.replace('data:image/jpeg;base64,', '');
}
var rawImage = this.decode64(origFileBase64);
var segments = this.slice2Segments(rawImage);
var image = this.exifManipulation(resizedFileBase64, segments);
return 'data:image/jpeg;base64,' + this.encode64(image);
};
ExifRestorer.exifManipulation = function (resizedFileBase64, segments) {
var exifArray = this.getExifArray(segments),
newImageArray = this.insertExif(resizedFileBase64, exifArray);
return new Uint8Array(newImageArray);
};
ExifRestorer.getExifArray = function (segments) {
var seg;
for (var x = 0; x < segments.length; x++) {
seg = segments[x];
if (seg[0] === 255 & seg[1] === 225) //(ff e1)
{
return seg;
}
}
return [];
};
ExifRestorer.insertExif = function (resizedFileBase64, exifArray) {
var imageData = resizedFileBase64.replace('data:image/jpeg;base64,', ''),
buf = this.decode64(imageData),
separatePoint = buf.indexOf(255, 3),
mae = buf.slice(0, separatePoint),
ato = buf.slice(separatePoint),
array = mae;
array = array.concat(exifArray);
array = array.concat(ato);
return array;
};
ExifRestorer.slice2Segments = function (rawImageArray) {
var head = 0,
segments = [];
while (1) {
if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 218) {
break;
}
if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 216) {
head += 2;
}
else {
var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],
endPoint = head + length + 2,
seg = rawImageArray.slice(head, endPoint);
segments.push(seg);
head = endPoint;
}
if (head > rawImageArray.length) {
break;
}
}
return segments;
};
ExifRestorer.decode64 = function (input) {
var chr1, chr2, chr3 = '',
enc1, enc2, enc3, enc4 = '',
i = 0,
buf = [];
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
var base64test = /[^A-Za-z0-9\+\/\=]/g;
if (base64test.exec(input)) {
console.log('There were invalid base64 characters in the input text.\n' +
'Valid base64 characters are A-Z, a-z, 0-9, ' + ', ' / ',and "="\n' +
'Expect errors in decoding.');
}
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
do {
enc1 = this.KEY_STR.indexOf(input.charAt(i++));
enc2 = this.KEY_STR.indexOf(input.charAt(i++));
enc3 = this.KEY_STR.indexOf(input.charAt(i++));
enc4 = this.KEY_STR.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
buf.push(chr1);
if (enc3 !== 64) {
buf.push(chr2);
}
if (enc4 !== 64) {
buf.push(chr3);
}
chr1 = chr2 = chr3 = '';
enc1 = enc2 = enc3 = enc4 = '';
} while (i < input.length);
return buf;
};
return ExifRestorer.restore(orig, resized); //<= EXIF
};
return upload;
}]);
var UserPurchaseController = function ($rootScope, $scope, $http, $location, $state, $timeout, $modal, $window, $sce, Lookups, Validations, CanonicalUrl, shApi, Purchases, Translator, $injector, shPurchase, AntiForgery) {
var srvinject;
//srvname, redirect, paymentMethods, currencies, clientCountry, clientLanguage.......
///
$scope.initialize = function (srvname, jsonDirectivesTranslations, buyerEmail) {
srvinject = $injector.get(srvname);
$scope.Model = {};
$scope.Math = Math;
$scope.Model.jsonDirectivesTranslations = jsonDirectivesTranslations;
$scope.Model.working = false;
$scope.Model.handled = false;
$scope.Model.focused = false;
$scope.Model.change = false;
$scope.Model.buyerEmail = buyerEmail;
$scope.Model.culture = Translator.getCurrentCulture();
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
AntiForgery.getAntiForgery($scope.Model.prefix).then(function (tok) {
$scope.Model.Token = tok;
});
$scope.Model.state = $state;
$scope.Model.ShowPurchaseConfirm = false;
$scope.Model.topIntegrationOffset = -90;
$scope.Model.pageError = null;
$scope.Model.continue = false;
$scope.Model.purchaseContact = null;
$scope.Model.firstStep = true;
$scope.Model.secondStep = false;
$scope.Model.thirdStep = false;
$scope.Model.showingIndex = -1;
$scope.Model.trackPackagedService = true;
$scope.Model.showRecommendations = false;
$scope.Model.serviceNotAvailableYet = false;
$scope.Model.showFading = true;
$scope.Model.dateOpen = [];
//datepicker
$scope.Model.availableDateOptions = shApi.datePickerOptions($scope.Model.culture);
$scope.Model.showMaterialEditionTemplatePopUp = false;
//MODALS
shApi.navigationStateControl($scope.Model);
shApi.defineRequired($scope, $scope.Model);
shApi.interceptor25x($scope, $scope.Model);
shApi.interceptor55x($scope, $scope.Model);
$scope.Model.lastRequestUid = null;
var args = arguments;
srvinject.initializeProcess(args, $scope, $scope.Model);
}
//Métodos generales
$scope.search = function () {
$scope.Model.loadMaterialized = true;
$scope.Model.materializedList = null;
$scope.Model.materializedMsg = null;
$scope.Model.searchingText = null;
var showOnScreenLimit = $scope.Model.showOnScreenLimit = null;
$scope.Model.limitResults = null;
$scope.Model.maxResults = 0;
$scope.Model.searchSkip = 0;
$scope.Model.searchTake = 10;
$scope.Model.searchFilters = {};
$scope.Model.searchFilters.serviceTab = $scope.Model.serviceTab;
$scope.Model.searchFilters.pointOrg = $scope.Model.pointOrg != undefined && $scope.Model.pointOrg.placeId != undefined ? $scope.Model.pointOrg : null;
$scope.Model.searchFilters.pointDest = $scope.Model.pointDest != undefined && $scope.Model.pointDest.placeId != undefined ? $scope.Model.pointDest : null;
//Si tiene algún servicio definido o en el caso de activities para las verticales
$scope.Model.searchFilters.serviceTypes = $scope.Model.serviceTypes != undefined ? $scope.Model.serviceTypes : null;
$scope.Model.searchFilters.numPeople = $scope.Model.numPeople != undefined ? $scope.Model.numPeople : 1;
$scope.Model.searchFilters.date = $scope.Model.date != undefined && $scope.Model.date != null ? shApi.serverUTCDateFromTime($scope.Model.date.getTime()) : null;
$scope.Model.searchFilters.languageCodeList = $scope.Model.languageCodeList != undefined ? $scope.Model.languageCodeList : null;
if ($scope.Model.serviceTab == "LodgingTab") {
showOnScreenLimit = 10;
$scope.Model.searchFilters.endDate = $scope.Model.endDate;
$scope.Model.searchFilters.detailedPeople = $scope.Model.detailedPeople;
}
else if ($scope.Model.serviceTab == "GuideTab" || $scope.Model.serviceTab == "TicketTab") {
$scope.Model.limitResults = 150;
showOnScreenLimit = $scope.Model.searchTake = 10;
$scope.Model.searchSkip = 0;
$scope.Model.searchFilters.destinations = $scope.Model.destinations;
$scope.Model.searchFilters.activityFilters = $scope.Model.activityFilter;
$scope.Model.searchFilters.textFilter = $scope.Model.textFilter;
$scope.Model.searchFilters.isFreeTour = $scope.Model.freeTours;
$scope.Model.searchFilters.quickFilterCode = $scope.Model.quickFilterCode;
$scope.Model.searchFilters.withFacetsCounter = true;
if ($scope.Model.filterOrder != undefined && $scope.Model.filterOrder != null) {
$scope.Model.searchFilters.filterOrder = [];
for (var index in $scope.Model.filterOrder) {
var fltr = {};
fltr.FilterType = $scope.Model.filterOrder[index];
fltr.Order = index;
$scope.Model.searchFilters.filterOrder.push(fltr);
}
}
else
$scope.Model.searchFilters.filterOrder = null;
}
else if ($scope.Model.serviceTab == "ChauffeurRouteTab") {
$scope.Model.searchFilters.detailedPeople = $scope.Model.detailedPeople;
$scope.Model.searchFilters.detailedBaggage = $scope.Model.detailedBaggage;
$scope.Model.flightNumber = $scope.Model.flightNumber;
$scope.Model.searchFilters.isRoundTrip = $scope.Model.isRoundTrip;
$scope.Model.searchFilters.returnDate = $scope.Model.isRoundTrip && $scope.Model.returnDate != null ? shApi.serverUTCDateFromTime($scope.Model.returnDate.getTime()) : null;
$scope.Model.searchFilters.returnFlightNumber = $scope.Model.returnFlightNumber;
$scope.Model.searchFilters.destinationFlightDate = $scope.Model.destinationFlightDate != undefined && $scope.Model.destinationFlightDate != null ? shApi.serverUTCDateFromTime($scope.Model.destinationFlightDate.getTime()) : null;
$scope.Model.searchFilters.returnDestinationFlightDate = $scope.Model.returnDestinationFlightDate != undefined && $scope.Model.returnDestinationFlightDate != null ? shApi.serverUTCDateFromTime($scope.Model.returnDestinationFlightDate.getTime()) : null;
$scope.Model.searchFilters.transferFilters = $scope.Model.transferFilters;
}
else if ($scope.Model.serviceTab == "ChauffeurByHoursTab") {
$scope.Model.searchFilters.detailedPeople = $scope.Model.detailedPeople;
$scope.Model.searchFilters.detailedBaggage = $scope.Model.detailedBaggage;
$scope.Model.searchFilters.minDuration = $scope.Model.minDuration;
$scope.Model.searchFilters.maxDuration = $scope.Model.maxDuration;
$scope.Model.searchingText = $scope.Model.pointOrg != undefined && $scope.Model.pointOrg != null ? $scope.Model.pointOrg.displayName : null;
}
$scope.Model.searchFilters.languageCode = $scope.Model.languageCode != undefined ? $scope.Model.languageCode : null;
$scope.Model.searchFilters.groupingCode = $scope.Model.groupingCode != undefined ? $scope.Model.groupingCode : null;
$scope.Model.searchFilters.includedProviders = $scope.Model.providers;
if ($scope.Model.sortType !== undefined) $scope.Model.searchFilters.sortType = $scope.Model.sortType;
$scope.Model.lastRequestUid = shApi.generateGuid();
Purchases.getMaterializedServices(JSON.stringify($scope.Model.searchFilters), $scope.Model.rqType, $scope.Model.partnerCode, $scope.Model.lastRequestUid, $scope.Model.prefix, $scope.Model.searchSkip, $scope.Model.searchTake, $scope.Model.currencyCode, $scope.Model.agentUid != undefined ? $scope.Model.agentUid : null)
.then(function (response) {
if (response.RequestUid === $scope.Model.lastRequestUid) {
$scope.Model.loadMaterialized = false;
$scope.Model.materializedList = response.MaterializedGroups;
$scope.Model.totalCount = response.TotalServices;
$scope.Model.materializedMsg = response.Message;
if ($scope.Model.lastFacets == undefined || $scope.Model.lastFacets == null) $scope.Model.lastFacets = {};
$scope.Model.lastFacets.categories = response.CountByFeature != undefined && response.CountByFeature != null ? response.CountByFeature.ActivityCategories : null;
$scope.Model.lastFacets.languages = response.CountByFeature != undefined && response.CountByFeature != null ? response.CountByFeature.Languages : null;
srvinject.processMaterialized($scope, $scope.Model);
if ($scope.Model.limitResults != null) $scope.Model.maxResults = Math.min($scope.Model.limitResults, $scope.Model.totalCount);
if (showOnScreenLimit != null) $scope.loadShowOnScreenLimit(showOnScreenLimit);
}
});
};
$scope.bookService = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
srvinject.saveCartBooking($scope, $scope.Model);
};
//controla la apertura de calendarios
$scope.open = function (e, prefix) {
shApi.preventNavigate(e);
switch (prefix) {
case 1: $scope.Model.openedDS = true; break;
}
};
$scope.validateDate = function (valDate, valHour, minDate, maxDate, validationHourPath, validationDatePath) {
var dateTime = shApi.getCompleteDateHour(valDate, valHour, 0);
if (dateTime.getTime() < minDate.getTime()) {
validationHourPath.$setValidity('mindate', false);
}
else {
validationHourPath.$setValidity('mindate', true);
}
if (maxDate != null) {
if (dateTime.getTime() > maxDate.getTime()) {
validationHourPath.$setValidity('maxdate', false);
}
else {
validationHourPath.$setValidity('maxdate', true);
}
}
if (validationHourPath.$valid) {
return true;
}
else {
return false;
}
};
//Tratar de unificar con otros métodos
$scope.addNewService = function (e) {
if (shApi.preventNavigate(e)) return;
srvinject.addNewService($scope, $scope.Model);
}
$scope.contains = function (array, input) {
return shApi.checkIfContains(array, input);
};
$scope.getCompleteDateHour = function (date, hour, addMinutes) {
return shApi.getCompleteDateHour(date, hour, addMinutes);
};
$scope.getDateSimplified = function (date) {
var dt = new Date(date);
dt.setSeconds(0, 0);
return dt;
}
$scope.selectFormat = function (i, custom) {
return i + ' ' + custom;
};
$scope.getPurchaseLanguages = function (filter) {
return Lookups.getPurchaseLanguages(filter, true, $scope.Model.prefix)
.then(function (response) {
return response;
});
}
$scope.getMeetingPointAddresses = function (filter) {
return Purchases.getMeetingPointAddressesCart(filter, $scope.Model.prefix, null, null, null).then(function (response) {
return response;
});
};
$scope.loadMore = function () {
if ($scope.Model.serviceTab == "GuideTab" || $scope.Model.serviceTab == "TicketTab") {
if ($scope.Model.totalCount > $scope.Model.materializedList.length && $scope.Model.limitResults > $scope.Model.materializedList.length) {
$scope.Model.loadMaterializedNewPage = true;
$scope.Model.searchSkip += $scope.Model.searchTake;
$scope.Model.searchTake = 20;
if (($scope.Model.searchSkip + $scope.Model.searchTake) > $scope.Model.limitResults)
$scope.Model.searchTake = $scope.Model.limitResults - $scope.Model.searchSkip;
$scope.Model.searchFilters.withFacetsCounter = false;
Purchases.getMaterializedServices(JSON.stringify($scope.Model.searchFilters), $scope.Model.rqType, $scope.Model.partnerCode, $scope.Model.lastRequestUid, $scope.Model.prefix, $scope.Model.searchSkip, $scope.Model.searchTake, $scope.Model.currencyCode, $scope.Model.agentUid)
.then(function (response) {
$scope.Model.loadMaterializedNewPage = false;
if (response.MaterializedGroups !== undefined && response.MaterializedGroups.length > 0) {
$scope.Model.lastRequestFailed = false;
$scope.Model.materializedList = $scope.Model.materializedList.concat(response.MaterializedGroups);
srvinject.processNewActivityMaterializedPaged($scope.Model);
$scope.Model.showOnScreenLimit = $scope.Model.materializedList.length;
}
else {
$scope.Model.lastRequestFailed = true;
}
});
}
}
else {
var showOnScreenLimit = $scope.Model.showOnScreenLimit + 20;
$scope.loadShowOnScreenLimit(showOnScreenLimit);
}
};
$scope.loadShowOnScreenLimit = function (showOnScreenLimit) {
if ($scope.Model.materializedList == null) $scope.Model.showOnScreenLimit = 0;
else if (showOnScreenLimit >= $scope.Model.materializedList.length) $scope.Model.showOnScreenLimit = $scope.Model.materializedList.length;
else $scope.Model.showOnScreenLimit = showOnScreenLimit;
}
$scope.$watch('Model.currentIndex', function (newValue, oldValue) {
if (newValue != undefined && newValue != null && newValue != oldValue) {
if (!$scope.Model.loadMaterializedNewPage && ($scope.Model.currentIndex + 21 >= $scope.Model.materializedList.length)) {
if ($scope.Model.previousSliderSendRequest && $scope.Model.lastRequestFailed) {
if (($scope.Model.currentIndex + 1) == $scope.Model.materializedList.length) {
$scope.loadMore();
$scope.Model.previousSliderSendRequest = true;
}
} else {
$scope.loadMore();
$scope.Model.previousSliderSendRequest = true;
}
}
else {
$scope.Model.previousSliderSendRequest = false;
}
}
else {
$scope.Model.previousSliderSendRequest = false;
}
});
// Back to top
var amountScrolled = 350;
$(window).scroll(function () {
if ($(window).scrollTop() > amountScrolled) {
$("#backToTop").addClass('back-to-top__show');
} else {
$("#backToTop").removeClass('back-to-top__show');
}
});
$scope.backToTop = function () {
$('html, body').animate({
scrollTop: 0
}, 600);
}
}
UserPurchaseController.$inject = ['$rootScope', '$scope', '$http', '$location', '$state', '$timeout', '$modal', '$window', '$sce', 'Lookups',
'Validations', 'CanonicalUrl', 'shApi', 'Purchases', 'Translator', '$injector', 'shPurchase', 'AntiForgery'];
var UserPurchaseBookingConfigurationController = function ($rootScope, $scope, $http, $location, $state, $timeout, $modal, $window, $sce, Lookups, Validations, CanonicalUrl, shApi, Purchases, Translator, $injector) {
var srvinject;
var xhrCount = 0;
//srvname, redirect, paymentMethods, currencies, clientCountry, clientLanguage.......
///
$scope.initialize = function (srvname) {
srvinject = $injector.get(srvname);
$scope.Model.culture = Translator.getCurrentCulture();
$scope.Model.dateOpen = [];
//datepicker
$scope.Model.availableDateOptions = shApi.datePickerOptions($scope.Model.culture);
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
////MODALS
// shApi.navigationStateControl($scope.Model);
// shApi.defineRequired($scope, $scope.Model);
// shApi.interceptor25x($scope, $scope.Model);
// shApi.interceptor55x($scope, $scope.Model);
srvinject.initializeProcess(arguments, $scope, $scope.Model);
}
$scope.initMaterializedData = function () {
srvinject.initMaterializedData($scope, $scope.Model);
}
$scope.recalculateMaterialized = function () {
srvinject.recalculateMaterialized($scope, $scope.Model);
}
$scope.saveBookingFromMaterialized = function () {
srvinject.saveBookingFromMaterialized($scope, $scope.Model);
}
$scope.closeMaterializedEdition = function () {
srvinject.closeMaterializedEdition($scope, $scope.Model);
}
}
UserPurchaseBookingConfigurationController.$inject = ['$rootScope', '$scope', '$http', '$location', '$state', '$timeout', '$modal', '$window', '$sce', 'Lookups', 'Validations', 'CanonicalUrl', 'shApi', 'Purchases', 'Translator', '$injector'];
var UserPurchaseCartController = function ($rootScope, $scope, shApi, $modal, $injector, $window, Translator) {
//initialize2
$scope.initialize = function (srvname) {
srvinject = $injector.get(srvname);
if ($scope.Model == undefined) $scope.Model = {};
$scope.Model.continue = false;
$scope.Model.pageError = null;
$scope.Model.showAlerts = {};
shApi.navigationStateControl($scope.Model);
shApi.defineRequired($scope, $scope.Model);
//shApi.interceptor25x($scope, $scope.Model);
shApi.interceptor55x($scope, $scope.Model);
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
srvinject.initializeProcess(arguments, $scope, $scope.Model);
}
$scope.addNewService = function (e) {
if (shApi.preventNavigate(e)) return;
srvinject.addNewService($scope, $scope.Model);
}
//Borrar servicios de cartdetails
//serviceGroup, index
$scope.deleteAllServices = function (e) {
srvinject.deleteAllServices(e, $scope.Model, $scope);
}
//Para mostrar los mensajes de borrar únicamente una vez por servicio
$scope.showDeleteAlert = function (e, id) {
if (shApi.preventNavigate(e, $scope.Model)) return;
if ($scope.Model.showingCartIndex != id) {
$scope.Model.showingCartIndex = id;
var deleteService = document.getElementById(id);
var slidebarShoppingCart = document.getElementById("allShoppingCart");
$(document).ready(function () {
$(slidebarShoppingCart).animate({
scrollTop: $(deleteService).offset().top
}, 700);
});
} else {
$scope.Model.showingCartIndex = -1;
}
}
$scope.deleteIndex = function (serviceGroup, id) {
$scope.Model.showingCartIndex = -1;
$scope.Model.showDeleteAlert = false;
$scope.Model.serviceGroupToDelete = serviceGroup;
srvinject.deleteServiceBooking(arguments, $scope, $scope.Model);
}
$scope.showCartDetail = function (e, id) {
if (shApi.preventNavigate(e, $scope.Model)) return;
$scope.Model.showingIndex = id;
}
//Aplicación de descuentos
$scope.applyDiscountCode = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
$scope.Model.errordiscount = null
srvinject.applyDiscountByCode($scope, $scope.Model);
};
}
UserPurchaseCartController.$inject = ['$rootScope', '$scope', 'shApi', '$modal', '$injector', '$window', 'Translator'];
var CheckoutController = function ($rootScope, $scope, shApi, $modal, $injector, $sce, Validations, Translator) {
var srvinject;
$scope.initialize = function (srvname) {
srvinject = $injector.get(srvname);
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
//MODALS
shApi.navigationStateControl($scope.Model);
shApi.defineRequired($scope, $scope.Model);
shApi.interceptor25x($scope, $scope.Model);
shApi.interceptor55x($scope, $scope.Model);
srvinject.initializeProcess(arguments, $scope, $scope.Model);
}
$scope.$watch('$scope.Model.registration.email', function (email) {
if ($scope.Model.binding) return;
$scope.Model.foundEmail = false;
if (email != null) {
if ($qtimer != null) $timeout.cancel($qtimer);
$qtimer = $timeout(function () { scope.checkClientEmail(email, false); }, 350);
}
});
$scope.checkClientEmail = function (email, dologin, timer) {
$scope.Model.loadingClientEmail = true;
Validations.existsClientEmail(email, $scope.Model.prefix).then(function (response) {
$scope.Model.binding = false;
$scope.Model.pageError = null;
$scope.Model.foundEmail = response.raw;
$scope.Model.loadingClientEmail = false;
$qtimer = null;
if (dologin) {
if ($scope.Model.foundEmail)
$scope.ConfirmClientLogin();
else
shApi.handleError($scope.Model, Translator.getTranslation('user_account_not_connected'), true);
}
});
}
$scope.ConfirmClientLogin = function (e, fromRegister) {
srvinject.ConfirmClientLogin($scope, $scope.Model, e, fromRegister);
};
$scope.clientAlreadyRegistered = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
$scope.Model.formClientData.$setUntouched();
$scope.Model.continue = false;
$scope.Model.showLoginRegister = true;
$scope.Model.showLogin = false;
$scope.Model.pageError = null;
$scope.Model.mainError = false;
$scope.Model.registrationError = false;
$scope.Model.password = '';
};
$scope.clientFirstTime = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
$scope.Model.formClientData.$setUntouched();
$scope.Model.continue = false;
$scope.Model.showLoginRegister = true;
$scope.Model.showLogin = true;
$scope.Model.pageError = null;
$scope.Model.mainError = false;
$scope.Model.registrationError = false;
$scope.Model.password = '';
};
$scope.closeLoginRegister = function (close) {
$scope.Model.continue = false;
$scope.Model.showLoginRegister = false;
$scope.Model.noShowLoginForm = false;
$scope.Model.incorrectLoginData = false;
}
//Common
$scope.trustAsHtml = function (html) {
return $sce.trustAsHtml(html);
}
}
CheckoutController.$inject = ['$rootScope', '$scope', 'shApi', '$modal', '$injector', '$sce', 'Validations', 'Translator'];
var ServiceSliderController = function ($rootScope, $scope, $state, shApi, $modal, $injector, $window, shPurchase, $stateParams, CanonicalUrl) {
$scope.initialize = function () {
if ($scope.Model == undefined) $scope.Model = {};
shApi.navigationStateControl($scope.Model);
shApi.defineRequired($scope, $scope.Model);
//shApi.interceptor25x($scope, $scope.Model);
shApi.interceptor55x($scope, $scope.Model);
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
if ($stateParams.activityid != undefined && $stateParams.activityid != null && $stateParams.groupingCode != undefined &&
$stateParams.groupingCode != null && $scope.Model.currentSrvList != undefined) {
$scope.showActivityInformation($stateParams.activityid, $stateParams.groupingCode, false);
}
}
$scope.$on('openServiceSlider', function (event, argument) {
$scope.showActivityInformation(event.materializedUid, event.groupingCode);
});
///Slider
$scope.showActivityInformation = function (materializedUid, groupingCode, alternativeProvider) {
var found = $scope.Model.currentSrvList.find(function (item) { return item.groupingCode == groupingCode; });
var idx = 0;
if (found != null) {
idx = $scope.Model.currentSrvList.indexOf(found);
}
$scope.Model.fromBtn = true;
$scope.loadActivityInfo(materializedUid, groupingCode, alternativeProvider);
$scope.Model.currentIndex = idx;
$scope.Model.sliderShow = true;
$scope.Model.working = false;
}
$scope.closeServiceSlider = function (e) {
if (e != undefined) if (shApi.preventNavigate(e, $scope.Model)) return;
$scope.Model.lastActivityRequestUid = null;
$scope.Model.sliderShow = false;
$scope.Model.fromBtn = false;
$('html, body').animate({
scrollTop: $("#purchaseResult" + $scope.Model.currentIndex).offset().top - 100
}, 0);
$scope.Model.currentIndex = null;
}
$scope.loadActivityInfo = function (materializedUid, groupingCode, alternativeProvider) {
shPurchase.loadActivityFullInfo($scope.Model, materializedUid, groupingCode, $scope.Model.currencyCode, 500, alternativeProvider);
};
$scope.$watch('Model.currentIndex', function (newValue, oldValue) {
if (newValue != undefined && newValue != null && newValue != oldValue && !$scope.Model.fromBtn) {
var current = $scope.Model.currentSrvList[$scope.Model.currentIndex];
$scope.loadActivityInfo(null, current.groupingCode, false);
}
$scope.Model.fromBtn = false;
});
}
ServiceSliderController.$inject = ['$rootScope', '$scope', '$state', 'shApi', '$modal', '$injector', '$window', 'shPurchase', '$stateParams', 'CanonicalUrl' ];
var ServantripMVCPurchaseApp = angular.module('ServantripMVCPurchaseApp', ['ui.router', 'ui.router.util', 'ui.bootstrap', 'ui.bootstrap.datepicker', 'ngLazyImage',
'ui.bootstrap.typeahead', 'ui.bootstrap.timepicker', 'ui.slider', 'ngLookupsService', 'ngValidationsService', 'ngCanonicalUrlService', 'angular-carousel',
'ngSharedDirectives', 'ngDynamicFormRender', 'ngSharedApi', 'ngSharedPurchase', 'ngPurchasesService', 'ngSharedCheckout', 'ngFileUpload', 'ngCookies', 'ngTranslator', 'ngAntiForgeryService',]);
ServantripMVCPurchaseApp.controller('UserPurchaseController', UserPurchaseController);
ServantripMVCPurchaseApp.controller('UserPurchaseBookingConfigurationController', UserPurchaseBookingConfigurationController);
ServantripMVCPurchaseApp.controller('ServiceSliderController', ServiceSliderController);
ServantripMVCPurchaseApp.controller('UserPurchaseCartController', UserPurchaseCartController);
ServantripMVCPurchaseApp.controller('CheckoutController', CheckoutController);
var configFunction = function ($stateProvider, $urlRouterProvider, $httpProvider, $locationProvider, $urlMatcherFactory) {
$locationProvider.hashPrefix('!').html5Mode({ enabled: true, requireBase: false });
$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
$httpProvider.interceptors.push('httpResponseInterceptor');
$stateProvider
.state('add-service-to-cart', {
url: $urlMatcherFactory.compile(":pre/{targeturl:theurl}"),
views: {
"mainPurchaseContainer": {
templateUrl: function ($stateParams) {
var prefix = '';
if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
prefix = '/' + $stateParams.pre;
return prefix + '/add-service-to-cart-ag';
}
},
}
})
.state('add-service-to-cart.driver', {
url: $urlMatcherFactory.compile(":pre/{targeturl:theurl}"),
params: { pre: null, targeturl: null, tab: null, clear: true },
views: {
"mainPurchaseContainer": {
templateUrl: function ($stateParams) {
var prefix = '';
if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
prefix = '/' + $stateParams.pre;
return prefix + '/add-service-to-cart-ag';
}
},
}
})
.state('add-service-to-cart.activities', {
url: $urlMatcherFactory.compile(":pre/{targeturl:theurl}"),
params: { pre: null, targeturl: null, tab: null, clear: false, fromLanding: false },
views: {
"mainPurchaseContainer": {
templateUrl: function ($stateParams) {
var prefix = '';
if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
prefix = '/' + $stateParams.pre;
return prefix + '/add-service-to-cart-ag';
}
},
}
})
.state('add-service-to-cart.transfer', {
url: $urlMatcherFactory.compile(":pre/{targeturl:theurl}"),
params: { pre: null, targeturl: null, tab: null, clear: true },
views: {
"mainPurchaseContainer": {
templateUrl: function ($stateParams) {
var prefix = '';
if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
prefix = '/' + $stateParams.pre;
return prefix + '/add-service-to-cart-ag';
}
},
}
})
.state('add-service-to-cart.tickets', {
url: $urlMatcherFactory.compile(":pre/{targeturl:theurl}"),
params: { pre: null, targeturl: null, tab: null, clear: true },
views: {
"mainPurchaseContainer": {
templateUrl: function ($stateParams) {
var prefix = '';
if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
prefix = '/' + $stateParams.pre;
return prefix + '/add-service-to-cart-ag';
}
},
}
})
.state('purchase-service-details', {
url: $urlMatcherFactory.compile(":pre/{targeturl:theurl}"),
params: { pre: null, targeturl: null, tab: null, activityid: null, groupingCode: null, clear: false, avoidLoading: false, fromLanding: false, timeStamp: null },
views: {
"mainPurchaseContainer": {
templateUrl: function ($stateParams) {
var prefix = '';
if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
prefix = '/' + $stateParams.pre;
return prefix + '/add-service-to-cart-ag';
}
},
"secondaryPurchaseContainer": {
templateUrl: function ($stateParams) {
var prefix = '';
if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
prefix = '/' + $stateParams.pre;
return prefix + '/purchase-service-details-ag';
}
},
}
})
.state('purchase-affiliate-results-load', {
url: $urlMatcherFactory.compile(":pre/{targeturl:theurl}"),
params: { pre: null, targeturl: null, tab: null, activityid: null, groupingCode: null, clear: false, fromLanding: null, urlParams: null, avoidLoading: false },
views: {
"mainPurchaseContainer": {
templateUrl: function ($stateParams) {
var prefix = '';
if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
prefix = '/' + $stateParams.pre;
return prefix + '/purchase-affiliate-results-load-ag';
}
},
}
})
//.state('show-cart-status', {
// url: $urlMatcherFactory.compile(":pre/{targeturl:theurl}"),
// views: {
// "mainPurchaseContainer": {
// templateUrl: function ($stateParams) {
// var prefix = '';
// if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
// prefix = '/' + $stateParams.pre;
// return prefix + '/show-cart-status-ag';
// }
// },
// "checkOutContainer": {
// templateUrl: function ($stateParams) {
// var prefix = '';
// if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
// prefix = '/' + $stateParams.pre;
// return prefix + '/cart-checkout-login-ag';
// }
// },
// }
//})
.state('show-cart-status', {
url: $urlMatcherFactory.compile(":pre/{targeturl:theurl}"),
views: {
"mainPurchaseContainer": {
templateUrl: function ($stateParams) {
var prefix = '';
if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
prefix = '/' + $stateParams.pre;
return prefix + '/show-cart-status-ag';
}
},
}
})
}
configFunction.$inject = ['$stateProvider', '$urlRouterProvider', '$httpProvider', '$locationProvider', '$urlMatcherFactoryProvider'];
ServantripMVCPurchaseApp.config(configFunction);
$(document).ready(function () {
$('[data-toggle="tooltip"]').tooltip(); //tooltip initialization
var _scroll = true, _timer = false, _floatbox = $("#contact_form"), _floatbox_opener = $(".contact-opener"), _floatbox_closer = $(".contact-closer");
_floatbox.css("right", "-320px").removeClass('visiable'); //initial contact form position
//Contact form Opener button
_floatbox_opener.click(function () {
if (_floatbox.hasClass('visiable')) {
_floatbox.animate({ "right": "-320px" }, { duration: 300 }).removeClass('visiable').removeClass('z-index-visiable');
} else {
_floatbox.animate({ "right": "0px" }, { duration: 300 }).addClass('visiable').addClass('z-index-visiable');
}
});
//only for close
_floatbox_closer.click(function () {
_floatbox.animate({ "right": "-320px" }, { duration: 300 }).removeClass('visiable');
_floatbox.removeClass('z-index-visiable');
})
});
function trackAnalyticsEvent(cat, ev, lbl) {
var dl = window.dataLayer = window.dataLayer || [];
dl.push({
event: 'callGAEvent',
attributes: {
route: window.location.href,
title: document.title,
category: cat,
action: ev,
label: lbl
}
});
}
(function () {
'use strict';
//TODO: Limpiar todo
var ngPurchasesService = angular.module('ngPurchasesService');
ngPurchasesService.service('PurchaseProcessStandard', function (CanonicalUrl, $http, shApi, $state, $cookies, $timeout, Validations, $sce, $window, Translator, shPurchase, Purchases, $stateParams, $rootScope) {
var $qtimer = null;
var map;
var directionsDisplay;
var directionsService;
var routeTab = 'ChauffeurRouteTab';
var driverTab = 'ChauffeurByHoursTab';
var activityTab = 'GuideTab';
var ticketTab = 'TicketTab';
this.initializeProcess = function (args, scope, model) {
var redirect = args[3];
var currencies = args[4];
var clientCountry = args[5];
var clientLanguage = args[6];
var payAllCode = args[7];
var paymentType = args[8];
model.showCheckOutContainer = false;
model.loggedClientName = "";
model.clientLoggedIn = false;
model.registrationError = false;
model.mainError = false;
model.firstLoadTimeClient = true;
model.firstLoadCart = true;
model.foundEmail = false;
model.showLanguage = false;
model.clientLanguage = null;
model.payAll = (payAllCode == paymentType);
model.packagedError = null;
model.showResumeStep1 = true;
model.showContactForm = false;
model.activityLanguagesLoaded = false;
model.activityCoverLoaded = false;
model.currentMaterializedUid = null;
model.currentMaterializedType = null;
model.showActivityDetailIframe = false;
model.showReviewModal = false;
model.existingEmail = false;
//model.showDestination = true;
model.cities = [];
model.baggageContactAllowed = false;
model.activitySortFilterOptions = args[9];
model.driverSortFilterOptions = args[10];
model.serviceTabs = args[11];
model.registration = {};
model.regData = {};
model.loadTransition = args[12];
//HLCN
var templateCart = document.getElementById('templateCart');
if (templateCart != null) templateCart.classList.remove("hidden");
if (clientCountry != null && typeof clientCountry.Dialcode != 'undefined') {
model.registration.phoneCode = model.anonymousPhoneCode = model.regData.phoneCode =
clientCountry.Dialcode;
}
if (clientLanguage != null && clientLanguage != "") {
model.clientLanguage = clientLanguage;
}
model.divisas = currencies;
var cookieval = $cookies.get("storedCurrency");
if (typeof cookieval != 'undefined' && cookieval != null) { //SI EXISTE COOKIE
var result = $.grep(model.divisas, function (e) { return e.Code == cookieval; });
if (result.length == 1) {
model.currencyNoChange = true;
model.divisa = model.selectorDivisa = result[0];
model.currencyCode = model.divisa.Code;
if (model.currencyCode != args[15]) {
internalSetCurrencyToCart(model, model.culture, model.currencyCode, false);
}
initializeStates(scope, model, redirect, args);
}
}
else {
model.showCurrencySelectionModal = true;
}
//From modal
scope.$watch('Model.modalDivisa', function (newVal, oldVal) {
if (newVal != undefined && newVal != null && newVal !== oldVal) {
model.currencyNoChange = true;
model.divisa = model.selectorDivisa = model.modalDivisa;
model.currencyCode = model.divisa.Code;
model.showCurrencySelectionModal = false;
internalSetCurrencyToCart(model, model.culture, model.currencyCode, false);
initializeStates(scope, model, redirect, args);
}
});
};
this.saveCartBooking = function (scope, model) {
//scope.saveBookingFromMaterialized();
};
this.addNewService = function (scope, model) {
$state.go('add-service-to-cart', { pre: CanonicalUrl.getFolderPrefix(model.culture), targeturl: CanonicalUrl.getCanonicalUrl(model.culture, 'add-service-to-cart') });
};
this.processMaterialized = function (scope, model) {
convertToMaterializedList(model);
};
this.processNewActivityMaterializedPaged = function (model) {
convertToMaterializedListActivityPaged(model);
};
function initializeStates(scope, model, redirect, args) {
addInitializers(scope, model);
addInternalMethods(scope, model);
if (redirect == 0) {
scope.goTabState(model.serviceTabs[0].key, true);
}
else if (redirect == 1)
$state.go('show-cart-status', { pre: CanonicalUrl.getFolderPrefix(model.culture), targeturl: CanonicalUrl.getCanonicalUrl(model.culture, 'show-cart-status') });
else if (redirect == 2) {
scope.goTabState(driverTab, true);
}
else if (redirect == 3) {
scope.goTabState(routeTab, true);
}
else if (redirect == 4) {
scope.goTabState(activityTab, true, false, null);
}
else if (redirect == 6) {
$state.go('purchase-affiliate-results-load', { pre: CanonicalUrl.getFolderPrefix(model.culture), targeturl: CanonicalUrl.getCanonicalUrl(model.culture, 'purchase-affiliate-results-load'), tab: activityTab, fromLanding: args[13], urlParams: args[14], clear: true, avoidLoading: true });
}
else if (redirect == 7) {
scope.goTabState(ticketTab, true);
}
}
function internalSetCurrencyToCart(model, culture, currencyCode, currencyChange) {
model.working = true;
$http.post(CanonicalUrl.getUrl(culture, 'cart-set-currency-ag'), {
currencyCode: currencyCode
})
.success(function (data, status, headers, config) {
model.working = false;
if (data != null) {
if (currencyChange || data.cartClean) $window.location.reload();
}
}).error(function (data, status, headers, config) {
model.working = false;
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
}
function addInitializers(scope, model) {
scope.initialize1 = function (srvmindate, srvmaxdate, minprice, maxprice, minduration, maxduration, today, rqType, searchminduration) {
$('.integration-body').addClass("integration-body--no-margin");
$window.stepFirst = model.stepFirst = true;
model.stepSecond = false;
model.loadMaterialized = false;
var headerBeforeCart = document.getElementById('headerBeforeCart');
if (headerBeforeCart != null) headerBeforeCart.classList.remove("hidden");
var headerAfterCart = document.getElementById('headerAfterCart');
if (headerAfterCart != null) headerAfterCart.classList.add("hidden");
model.rqType = rqType;
model.showIconList = false;
model.minServiceDate = shApi.getUTCDateFromTime(srvmindate);
model.maxServiceDate = shApi.getUTCDateFromTime(srvmaxdate);
model.showIconList = false;
//4hours gap
model.minServiceReturnDate = shApi.getCompleteDateHour(model.minServiceDate, model.minServiceDate, 240);
model.maxServiceReturnDate = shApi.getCompleteDateHour(model.maxServiceDate, model.maxServiceDate, 0);
model.returnDateServiceMinValue = shApi.getCompleteDateHour(model.dateService, model.hourService, 240);
model.durationOptions = {};
model.durationOptions.range = [];
model.durationOptions.range.push(4);
model.durationOptions.range.push(maxduration);
model.durationOptions.step = 1;
model.durationOptionsActivities = {};
model.durationOptionsActivities.range = [];
model.durationOptionsActivities.range.push(searchminduration);
model.durationOptionsActivities.range.push(maxduration);
model.durationOptionsActivities.step = 1;
model.minRangeDuration = searchminduration;
model.maxRangeDuration = maxduration;
model.minDefaultDate = shApi.getCompleteDateHour(model.minServiceDate, model.minServiceDate, 10080);
model.minServiceReturnDate =
shApi.getCompleteDateHour(model.minDefaultDate, model.minDefaultDate, 240);
//Inicialización Formulario contacto
model.contact = {};
model.continue = false;
if (model.loadTransition) loadHeaderTransition();
if ($stateParams.clear) {
model.activitySortType = null;
model.driverSortType = null;
var tab = shApi.returnByProperty(model.serviceTabs, 'key', $stateParams.tab);
model.materializedList = null;
model.materializedMsg = null;
model.lastfilters = null;
model.totalCount = 0;
model.showOnScreenLimit = 0;
scope.initializeTabFromState(tab);
}
else {
//Set values in directive
if ($stateParams.tab == activityTab && $stateParams.fromLanding != undefined && $stateParams.fromLanding) {
var tab = shApi.returnByProperty(model.serviceTabs, 'key', $stateParams.tab);
model.serviceTab = model.selectTab = tab.key;
model.showActivitiesFilters = false;
scope.reloadFilters(model.lastfilters);
}
}
if ($stateParams.tab == activityTab) {
loadActivityCoverData(model);
}
}
scope.initialize2 = function () {
model.materializedList = null;
model.materializedMsg = null;
model.lastfilters = null;
model.totalCount = 0;
model.showOnScreenLimit = 0;
if ($stateParams.fromLanding != undefined && $stateParams.fromLanding && $stateParams.urlParams != undefined && $stateParams.urlParams != null) {
scope.loadActivitySliderFromParams($stateParams.urlParams);
}
}
}
function addInternalMethods(scope, model) {
function initializeRouteFilters() {
model.routeFilters = {};
model.routeFilters.pointOrg = null;
model.routeFilters.pointDest = null;
model.routeFilters.date = model.minDefaultDate;
model.routeFilters.isRoundTrip = false;
model.routeFilters.returnDate = model.minServiceReturnDate;
model.routeFilters.people = {};
model.routeFilters.people.numPeople = 1;
model.routeFilters.people.detailedPeople = {};
model.routeFilters.people.detailedPeople.adults = 1;
model.routeFilters.people.detailedPeople.childrenUnderFive = 0;
model.routeFilters.people.detailedPeople.childrenUnderTwelve = 0;
model.routeFilters.transferFilters = [];
model.routeFilters.transferFilters.push('Private');
model.driverSortType = model.driverSortFilterOptions[0];
}
function initializeHoursFilters() {
model.hourFilters = {};
model.hourFilters.date = model.minDefaultDate;
model.hourFilters.people = {};
model.hourFilters.people.numPeople = 1;
model.hourFilters.people.detailedPeople = {};
model.hourFilters.people.detailedPeople.adults = 1;
model.hourFilters.people.detailedPeople.childrenUnderFive = 0;
model.hourFilters.people.detailedPeople.childrenUnderTwelve = 0;
model.hourFilters.durationRange = [4, 4];
model.hourFilters.selectedLanguages = [];
model.hourFilters.pointOrg = null;
model.driverSortType = model.driverSortFilterOptions[0];
}
scope.reloadFilters = function (filters) {
model.activityFilters.searchTrigger = '';
model.activityFilters.date = filters != undefined && filters.date != undefined ? angular.copy(filters.date) : null;
model.activityFilters.verticals = filters != undefined && filters.verticals != undefined ? angular.copy(filters.verticals) : [];
model.activityFilters.textFilter = filters != undefined && filters.textFilter != undefined ? angular.copy(filters.textFilter) : null;
model.activityFilters.language = filters != undefined && filters.language != undefined ? angular.copy(filters.language) : null;
model.activityFilters.durationRange = [model.minRangeDuration, model.maxRangeDuration];
model.activitySortType = model.activitySortType == undefined || model.activitySortType == null ? model.activitySortFilterOptions[0] : model.activitySortType;
if (filters != undefined && filters.destinations != undefined && filters.destinations != null && filters.destinations.length > 0) {
scope.avoidSearchDestination = true;
scope.loadCity(null, filters.destinations[0].displayName, filters.destinations[0].placeId);
model.lastfilters = angular.copy(model.activityFilters);
model.showActivitiesFilters = true;
}
else
model.activityFilters.destinations = [];
}
function initializeActivityFilters() {
if (model.activityFilters == undefined) model.activityFilters = {};
model.activityFilters.destinations = [];
model.activityFilters.filterOrder = [];
model.activityFilters.date = null;
model.activityFilters.verticals = [];
model.activityFilters.textFilter = null;
model.activityFilters.language = null;
model.activityFilters.freeTours = false;
model.activityFilters.durationRange = [model.minRangeDuration, model.maxRangeDuration];
model.activitySortType = model.activitySortType == undefined || model.activitySortType == null ? model.activitySortFilterOptions[0] : model.activitySortType;
}
function initializeTicketFilters() {
if (model.ticketFilters == undefined) model.ticketFilters = {};
model.ticketFilters.destinations = [];
model.ticketFilters.date = null;
model.ticketFilters.verticals = [];
model.ticketFilters.textFilter = null;
model.ticketFilters.language = null;
model.ticketFilters.freeTours = false;
model.ticketFilters.durationRange = [model.minRangeDuration, model.maxRangeDuration];
model.activitySortType = model.activitySortType == undefined || model.activitySortType == null ? model.activitySortFilterOptions[0] : model.activitySortType;
}
function fillDataActivity(filters) {
model.date = filters.date;
model.destinations = filters.destinations;
model.activityFilter = filters.verticals;
model.textFilter = filters.textFilter;
model.freeTours = filters.freeTours;
//Update elements
model.updateCategories = filters.updateCategories;
model.updateLanguages = filters.updateLanguages;
model.languageCodeList = null;
if (filters.language != null) {
model.languageCodeList = filters.language;
}
//model.minDuration = filters.durationRange;
//model.maxDuration = filters.durationRange;
model.sortType = model.activitySortType.key;
}
function fillDataTicket(filters) {
fillDataActivity(filters);
}
//Fill data for send to server
function fillData(filters) {
model.pointOrg = filters.pointOrg;
model.pointDest = filters.pointDest;
model.numPeople = filters.people.numPeople;
model.date = filters.date;
model.isRoundTrip = filters.isRoundTrip;
if (filters.isRoundTrip) {
model.returnDate = filters.returnDate;
}
model.minDuration = null;
model.maxDuration = null;
if (filters.durationRange != undefined && filters.durationRange != null && filters.durationRange.length > 0) {
model.minDuration = filters.durationRange[0];
model.maxDuration = filters.durationRange[1];
}
model.detailedPeople = filters.people.detailedPeople;
model.languageCodeList = null;
if (filters.selectedLanguages != null) {
model.languageCodeList = [];
for (var index in filters.selectedLanguages) {
var language = filters.selectedLanguages[index];
model.languageCodeList.push(language.Code);
}
}
model.transferFilters = filters.transferFilters;
}
scope.setDate = function () {
model.routeFilters.date = new Date();
}
scope.saveBookingFromMaterialized = function () {
}
scope.setTestParams = function () {
model.routeFilters.date = null;
}
scope.selectTabView = function (e, tab) {
if (e != undefined) if (shApi.preventNavigate(e)) return;
scope.selectTab(tab);
};
scope.selectTab = function (tab, currencyNoChange) {
if (tab.key != model.serviceTab) {
scope.goTabState(tab.key, true);
}
};
scope.initializeTabFromState = function (tab) {
model.serviceTab = model.selectTab = tab.key;
if (tab.key == routeTab) {
model.showDriverFilters = false;
model.showTransferFilters = false;
initializeRouteFilters();
}
else if (tab.key == driverTab) {
model.showDriverFilters = false;
initializeHoursFilters();
}
else if (tab.key == activityTab) {
model.showActivitiesFilters = false;
initializeActivityFilters();
}
else if (tab.key == ticketTab) {
model.showTicketFilters = false;
initializeTicketFilters();
}
}
scope.goTabState = function (tab, clear, fromLanding) {
if (tab == routeTab) {
$state.go('add-service-to-cart.transfer', { pre: CanonicalUrl.getFolderPrefix(model.culture), targeturl: CanonicalUrl.getCanonicalUrl(model.culture, 'add-service-to-cart/transfer'), tab: tab, clear: clear });
}
else if (tab == driverTab) {
$state.go('add-service-to-cart.driver', { pre: CanonicalUrl.getFolderPrefix(model.culture), targeturl: CanonicalUrl.getCanonicalUrl(model.culture, 'add-service-to-cart/driver'), tab: tab, clear: clear });
}
else if (tab == activityTab) {
$state.go('add-service-to-cart.activities', { pre: CanonicalUrl.getFolderPrefix(model.culture), targeturl: CanonicalUrl.getCanonicalUrl(model.culture, 'add-service-to-cart/activities'), tab: tab, clear: clear, fromLanding: true });
}
else if (tab == ticketTab) {
$state.go('add-service-to-cart.tickets', { pre: CanonicalUrl.getFolderPrefix(model.culture), targeturl: CanonicalUrl.getCanonicalUrl(model.culture, 'add-service-to-cart/tickets'), tab: tab, clear: clear });
}
};
//Aterrizaje en actividades desde landing
scope.loadActivitySliderFromParams = function (params) {
var limit = model.limit = 10;
var dateUtc = null;
model.materializedList = null;
model.materializedMsg = null;
model.totalCount = 0;
model.showOnScreenLimit = 0;
model.lastRequestUid = shApi.generateGuid();
if (params.date != undefined && params.date != null) {
dateUtc = shApi.getUTCDateFromString(params.date);
}
Purchases.getActivityMaterializedServicesByIds(JSON.stringify(params.activityIds), dateUtc != null ? shApi.serverUTCDateFromTime(dateUtc.getTime()) : null, model.partnerCode, model.lastRequestUid, model.prefix, params.mainId, model.activitySortFilterOptions[0].key, model.currencyCode)
.then(function (response) {
model.materializedList = response.MaterializedGroups;
model.totalCount = response.TotalServices;
model.materializedMsg = response.Message;
convertToMaterializedList(model);
model.showOnScreenLimit = model.materializedList.length;
model.maxResults = model.totalCount;
var materializedUid = response.MainMaterializedUid;
var groupingCode = response.MainGroupingCode;
model.loadingLandingActivities = false;
model.activityFilters = {};
if (dateUtc != null) {
model.activityFilters.date = dateUtc;
}
else
model.activityFilters.date = null;
if (response.ReferenceDestination != null) {
scope.avoidSearchDestination = true;
scope.loadCity(null, response.ReferenceDestination.DisplayName, response.ReferenceDestination.PlaceId);
model.lastfilters = angular.copy(model.activityFilters);
}
if (model.materializedList.length > 0) {
model.lastfilters = angular.copy(model.activityFilters);
if (materializedUid != null && groupingCode != null) {
//Open slider with values
$state.go('purchase-service-details', { pre: CanonicalUrl.getFolderPrefix(model.culture), targeturl: CanonicalUrl.getCanonicalUrl(model.culture, 'purchase-service-details'), tab: activityTab, activityid: materializedUid, groupingCode: groupingCode, clear: false, avoidLoading: true, fromLanding: true, timeStamp: Date.now() });
}
else {
scope.goTabState(activityTab, false, true);
}
}
else {
scope.goTabState(activityTab, true);
}
});
};
scope.getDestinationPrediction = function (filter) {
return Purchases.getDestinationPrediction(filter, model.prefix)
.then(function (response) {
return response;
});
};
scope.closeDeleteBooking = function () {
model.showingCartIndex = -1;
}
scope.continueBooking = function (e) {
model.showingCartIndex = -1;
setTimeout(function () {
$('html').removeClass('delete-scroll');
$('body').removeClass('delete-scroll');
$('html').css('padding-right', '');
$('html').css('overflow-y', '');
}, 1000);
if (shApi.preventNavigate(e, model)) return;
$state.go('show-cart-status', { pre: CanonicalUrl.getFolderPrefix(model.culture), targeturl: CanonicalUrl.getCanonicalUrl(model.culture, 'show-cart-status') }).then(function () { });
}
scope.$watch('Model.transportationFilters.transferOption.$viewValue', function (newVal, oldVal) {
if (newVal !== oldVal) {
if (newVal == "option2") {
model.isRoundTrip = true;
}
else {
model.isRoundTrip = false;
}
}
});
scope.$watch('Model.routeFilters.searchTrigger', function (newValue, oldValue) {
if (newValue !== undefined && newValue.length > 0) {
scope.searchFiltered();
model.routeFilters.searchTrigger = '';
}
});
scope.$watch('Model.hourFilters.searchTrigger', function (newValue, oldValue) {
if (newValue !== undefined && newValue.length > 0) {
scope.searchFiltered();
model.hourFilters.searchTrigger = '';
}
});
scope.$watch('Model.activityFilters.searchTrigger', function (newValue, oldValue) {
if (newValue !== undefined && newValue.length > 0 && !scope.avoidSearchDestination) {
model.activityFilters.filterOrder = shPurchase.establishFiltersOrder(model.activityFilters.filterOrder, newValue, model.activityFilters);
scope.searchFiltered();
model.activityFilters.searchTrigger = '';
}
scope.avoidSearchDestination = false;
});
scope.$watch('Model.ticketFilters.searchTrigger', function (newValue, oldValue) {
if (newValue !== undefined && newValue.length > 0) {
model.ticketFilters.filterOrder = shPurchase.establishFiltersOrder(model.ticketFilters.filterOrder, newValue, model.ticketFilters);
scope.searchFiltered();
model.ticketFilters.searchTrigger = '';
}
});
scope.$watch('Model.activitySortType', function (newValue, oldValue) {
if (newValue != undefined && newValue != null && newValue != oldValue) {
if (model.selectTab == activityTab) {
model.activityFilters.searchTrigger = 'sort';
}
else if (model.selectTab == ticketTab) {
model.ticketFilters.searchTrigger = 'sort';
}
}
});
scope.$watch('Model.driverSortType', function (newValue, oldValue) {
if (newValue != undefined && newValue != null && newValue != oldValue) {
if (model.selectTab == routeTab) {
model.routeFilters.searchTrigger = 'sort';
}
else if (model.selectTab == driverTab) {
model.hourFilters.searchTrigger = 'sort';
}
}
});
scope.searchFiltered = function () {
if (model.selectTab == routeTab && model.routeFilters.pointOrg != null && model.routeFilters.pointOrg.placeId != null &&
model.routeFilters.pointDest != null && model.routeFilters.pointDest.placeId != null
&& model.transportationFormValid) {
fillData(model.routeFilters);
scope.search();
}
else if (model.selectTab == driverTab && model.hourFilters.pointOrg != null && model.hourFilters.pointOrg.placeId != null && model.bookingHoursFormValid) {
fillData(model.hourFilters);
scope.search();
}
else if (model.selectTab == activityTab && model.bookingActivitiesFormValid
&& model.activityFilters.destinations != null && model.activityFilters.destinations.length > 0) {
fillDataActivity(model.activityFilters);
scope.search();
}
else if (model.selectTab == ticketTab && model.bookingTicketsFormValid
&& (model.ticketFilters.destinations != null && model.ticketFilters.destinations.length > 0)) {
fillDataTicket(model.ticketFilters);
scope.search();
}
}
scope.selectMaterializedService = function (materializedUid, type) {
model.currentMaterializedUid = materializedUid;
model.currentMaterializedType = type;
$('body').css('padding-right', '');
};
scope.loadCity = function (e, cityName, placeId) {
if (e != undefined) if (shApi.preventNavigate(e, model)) return;
var city = {};
city.placeId = placeId;
city.displayName = cityName;
var list = [];
list.push(city);
model.activityFilters.destinations = list;
};
scope.showMoreDeals = function (e, index) {
if (e != undefined) if (shApi.preventNavigate(e, model)) return;
model.showingMoreDeals == index ? model.showingMoreDeals = -1 : model.showingMoreDeals = index;
}
scope.modalOverflow = function() {
if ($("body").hasClass("overflow-consolidator") == true) {
$("body").removeClass("overflow-consolidator");
$("html").removeClass("overflow-consolidator");
} else {
$("body").addClass("overflow-consolidator");
$("html").addClass("overflow-consolidator");
}
}
scope.showServiceSlider = function (e, materializedUid, groupingCode) {
if (e != undefined) if (shApi.preventNavigate(e, model)) return;
if (model.selectTab == activityTab) {
model.lastfilters = angular.copy(model.activityFilters);
}
else if (model.selectTab == ticketTab) {
model.lastfilters = angular.copy(model.ticketFilters);
}
$state.go('purchase-service-details', { pre: CanonicalUrl.getFolderPrefix(model.culture), targeturl: CanonicalUrl.getCanonicalUrl(model.culture, 'purchase-service-details'), tab: activityTab, activityid: materializedUid, groupingCode: groupingCode, timeStamp: Date.now() });
}
scope.activityInformationFromCover = function (materializedUid, groupingCode, type) {
if (type == 'topTours')
model.currentSrvList = model.topToursSliderData;
else if (type == 'bestOffers')
model.currentSrvList = model.bestOffersSliderData;
$state.go('purchase-service-details', { pre: CanonicalUrl.getFolderPrefix(model.culture), targeturl: CanonicalUrl.getCanonicalUrl(model.culture, 'purchase-service-details'), tab: activityTab, activityid: materializedUid, groupingCode: groupingCode, timeStamp: Date.now() });
};
/////////////////////////
scope.$watch('Model.contact.contactFormDate', function (newDate, oldDate) {
if (newDate != undefined && newDate != null && newDate !== oldDate) {
scope.validateDate(newDate, model.contact.contactFormHour, model.minServiceDate, null, model.contactForm.contactFormHour);
}
});
scope.$watch('Model.contact.contactFormHour', function (newDate, oldDate) {
if (newDate != undefined && newDate != null && newDate !== oldDate) {
scope.validateDate(model.contact.contactFormDate, newDate, model.minServiceDate, null, model.contactForm.contactFormHour);
}
});
//Formulario de contacto
scope.openContactForm = function (e, type) {
if (shApi.preventNavigate(e)) return;
//Initialize contact form values
//Initialize contact form values
if (model.anonymousPhoneCode != undefined)
model.contact.anonymousPhoneCode = model.anonymousPhoneCode;
if (model.selectTab == routeTab)
model.contact.contactFormDate = model.contact.contactFormHour = model.routeFilters.date;
else if (model.selectTab == driverTab)
model.contact.contactFormDate = model.contact.contactFormHour = model.hourFilters.date;
else if (model.selectTab == activityTab)
model.contact.contactFormDate = model.contact.contactFormHour = model.activityFilters.date;
model.contact.anonymousEmail = '';
model.contact.anonymousPhone = null;
model.contact.anonymousName = null;
model.contact.anonymousMsg = '';
model.contact.selectedHitType = null;
if (type != undefined) {
for (var i in model.hitTypes) {
if (model.hitTypes[i].key == type) {
model.contact.selectedHitType = model.hitTypes[i];
break;
}
};
}
if (model.contact.selectedHitType == null) model.contact.selectedHitType = model.hitTypes[3]; //def
model.contacted = false;
model.showContactForm = true;
//$('#modalContact').modal('show');
};
scope.closeContactForm = function () {
model.showContactForm = false;
}
/*Slider imágenes*/
scope.showImagesSlider = function (imagesList) {
model.currentImagesList = [];
$.each(imagesList, function (id, val) {
model.currentImagesList.push({
key: id,
value: val
});
});
if (model.currentImagesList.length > 0) {
model.currentIndexImage = 0;
model.sliderShowImages = true;
$('html').addClass('delete-scroll');
}
}
scope.closeImagesSlider = function (e) {
if (e != undefined) if (shApi.preventNavigate(e, model)) return;
model.currentIndexImage = null;
model.currentImagesList = null;
model.sliderShowImages = false;
$('html').removeClass('delete-scroll');
};
//**********//
scope.internalRefreshCartData = function (showWorking, model, scope) {
model.working = showWorking;
model.errordiscount = null;
$http.post(CanonicalUrl.getUrl(model.culture, 'cart-data-ag'), {}).success(function (data, status, headers, config) {
scope.loadGroupedDetails(data, model);
model.firstLoadCart = false;
model.working = false;
}).error(function (data, status, headers, config) {
model.working = false;
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, true);
});
}
scope.loadGroupedDetails = function (data, model) {
model.cartDetail = {
details: data.bookingPackages,
summary: data.summary,
discount: data.discount
};
///Hit contact
var numItems = $(".shopping-cart .cart-icon .num");
if (numItems != undefined && numItems != null) {
var length = model.cartDetail.details.length;
if (length > 0) {
if (numItems.hasClass("hidden")) {
numItems.removeClass("hidden");
}
numItems.children("span").text(length);
}
else {
if (!numItems.hasClass("hidden")) {
numItems.addClass("hidden");
numItems.children("span").text(length);
}
}
}
};
///Hit contact
scope.saveHitContact = function (e) {
if (shApi.preventNavigate(e, model)) return;
//if (typeof model.anonymousEmail != 'undefined' && model.anonymousEmail != '') {
// trackAnalyticsEvent('ConForm', 'PPAC', 'Contact Form Not Available City Sent');
//}
if (model.contactForm.$valid && model.contact.anonymousEmail != '' && model.contact.anonymousMsg != '') {
model.working = true;
var dateHour = shApi.getCompleteDateHour(model.contact.contactFormDate, model.contact.contactFormHour);
var type = model.contact.selectedHitType;
$http.post(CanonicalUrl.getUrl(model.culture, 'purchase-contact-city-hit-ag'), {
requestUid: model.lastRequestUid,
email: model.contact.anonymousEmail,
name: model.contact.anonymousName,
phoneCode: model.contact.anonymousPhoneCode,
phone: model.contact.anonymousPhone,
notes: model.contact.anonymousMsg,
dateHour: shApi.serverUTCDateFromTime(dateHour.getTime()),
hitType: type != null ? type.key : null,
serviceTab: model.selectTab,
})
.success(function (data, status, headers, config) {
model.working = false;
if (data != 'true') {
shApi.handleError(model, data, true);
}
else {
model.contacted = true;
model.pageError = null;
}
})
.error(function (data, status, headers, config) {
model.working = false;
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
} else {
model.continue = true;
$window.setTimeout(function () { shApi.scrollToError(model.topIntegrationOffset); }, 350);
}
};
scope.returnToPurchase = function (e) {
if (e != undefined) {
if (shApi.preventNavigate(e, model)) return;
}
$state.go('add-service-to-cart', { pre: CanonicalUrl.getFolderPrefix(model.culture), targeturl: CanonicalUrl.getCanonicalUrl(model.culture, 'add-service-to-cart') });
}
///Monedas
scope.$watch('Model.selectorDivisa', function (newVal, oldVal) {
if (newVal != oldVal && !model.currencyNoChange) {
model.showCurrencyChangeAlert = true;
}
model.currencyNoChange = false;
});
scope.acceptChangeCurrency = function (e) {
if (e != undefined && shApi.preventNavigate(e, model)) return;
model.divisa = angular.copy(model.selectorDivisa);
model.currencyCode = model.selectorDivisa.Code;
internalSetCurrencyToCart(model, model.culture, model.currencyCode, true);
}
scope.cancelChangeCurrency = function (e) {
if (shApi.preventNavigate(e, model)) return;
model.currencyNoChange = true;
model.selectorDivisa = angular.copy(model.divisa);
model.showCurrencyChangeAlert = false;
}
};
function loadActivityCoverData(model) {
if (!model.activityCoverLoaded) {
model.loadingCoverData = true;
Purchases.getActivityCoverData(model.prefix, model.partnerCode, model.currencyCode)
.then(function (response) {
model.topDestinations = response.TopDestinations;
model.topOffers = response.TopOffers;
model.topTours = response.TopTours;
if (model.topOffers != undefined && model.topOffers != null) {
model.bestOffersSliderData = initToursSlider(model, 'bestOffers');
}
if (model.topTours != undefined && model.topTours != null) {
model.topToursSliderData = initToursSlider(model, 'topTours');
}
model.loadingCoverData = false;
model.activityCoverLoaded = true;
});
}
}
function initToursSlider(model, type) {
var list = [];
var tours = [];
if (type == 'topTours') {
tours = model.topTours;
}
else if (type == 'bestOffers') {
tours = model.topOffers;
}
$.each(tours, function (idx, item) {
var elem = {};
elem = {};
elem.list = [];
elem.listkeys = []; //para pantalla
elem.groupingCode = item.MaterializedUid;
if (type == 'topTours') {
model.topTours[idx].GroupingCode = elem.groupingCode;
}
else if (type == 'bestOffers') {
model.topOffers[idx].GroupingCode = elem.groupingCode;
}
elem.groupingIndex = idx;
elem.currentMaterializedUid = item.MaterializedUid;;
var materialized = {};
materialized.fullDataLoaded = false;
materialized.detail = {};
materialized.detail.Title = item.Title;
materialized.detail.MainPicture = item.ImgUrl;
materialized.detail.ProviderLogoUrl = item.ProviderLogoUrl;
materialized.detail.Subtitle = item.Subtitle;
materialized.detail.CategoryName = item.CategoryName;
materialized.detail.Price = {};
materialized.detail.Price.PVP = item.Price.PVP;
materialized.detail.Price.CurrencyMask = item.Price.CurrencyMask;
elem.listkeys.push(item.MaterializedUid);
elem.list[item.MaterializedUid] = materialized;
list.push(elem);
});
return list;
};
function loadHeaderTransition() {
$(document).ready(function () {
headerTransition();
});
$(window).scroll(function () {
headerTransition();
});
function headerTransition() {
if ($window.stepFirst) {
if ($(window).scrollTop() > 50) {
$('header').removeClass("big");
} else {
$('header').addClass("big");
}
}
}
}
function convertToMaterializedList(model) {
model.currentSrvList = [];
model.showingIconList = -1;
model.showingIconListMobile = -1;
model.showingIndex = -1;
model.showingIconListMobileActivities = -1;
model.showingMoreDeals = -1;
for (var group in model.materializedList) {
model.materializedList[group].pricesToShow = [];
for (var i = 1; i < 3; i++) {
var mat = {};
var currentSrv = model.materializedList[group].MaterializedServices[i];
if (currentSrv !== undefined) {
mat.show = true;
mat.price = currentSrv.Prices.FinalTotal;
mat.providerName = currentSrv.ProviderName;
mat.materializedUid = currentSrv.MaterializedUid;
mat.currencyMask = currentSrv.Prices.CurrencyMask;
}
else {
mat.show = false;
}
model.materializedList[group].pricesToShow.push(mat);
}
$.each(model.materializedList[group].MaterializedServices, function (srv, val) {
var policies = [];
model.materializedList[group].MaterializedServices[srv].tooltipPolicies = null;
if (val.CancellationPolicies.Names != null) {
$.each(val.CancellationPolicies.Names, function (policie, valPol) {
policies.push(valPol.LongVersion);
model.materializedList[group].MaterializedServices[srv].tooltipPolicies = policies.join(' ');
});
}
});
if ($stateParams.tab == activityTab || $stateParams.tab == ticketTab) {
shPurchase.initServiceSliderList(model, group);
}
}
}
function convertToMaterializedListActivityPaged(model) {
var currentSrvListLength = model.currentSrvList.length;
model.showingIconList = -1;
model.showingIconListMobile = -1;
model.showingIndex = -1;
model.showingIconListMobileActivities = -1;
model.showingMoreDeals = -1;
for (var group in model.materializedList.slice(currentSrvListLength)) {
var realIndex = parseInt(group) + currentSrvListLength;
model.materializedList[realIndex].pricesToShow = [];
for (i = 1; i < 3; i++) {
var mat = {};
var currentSrv = model.materializedList[realIndex].MaterializedServices[i];
if (currentSrv !== undefined) {
mat.show = true;
mat.price = currentSrv.Prices.FinalTotal;
mat.providerName = currentSrv.ProviderName;
mat.materializedUid = currentSrv.MaterializedUid;
}
else {
mat.show = false;
}
model.materializedList[realIndex].pricesToShow.push(mat);
}
$.each(model.materializedList[realIndex].MaterializedServices, function (srv, val) {
var policies = [];
model.materializedList[realIndex].MaterializedServices[srv].tooltipPolicies = null;
if (val.CancellationPolicies.Names != null) {
$.each(val.CancellationPolicies.Names, function (policie, valPol) {
policies.push(valPol.LongVersion);
model.materializedList[realIndex].MaterializedServices[srv].tooltipPolicies = policies.join(' ');
});
}
});
if ($stateParams.tab == activityTab) {
shPurchase.initServiceSliderList(model, realIndex);
}
}
}
});
})();
(function () {
'use strict';
//TODO: Limpiar todo
var ngPurchasesService = angular.module('ngPurchasesService');
ngPurchasesService.service('BookingConfigActivitiesStandard', function (CanonicalUrl, $http, shApi, $state, $cookies, $timeout, Validations, $sce, $window, Translator, shPurchase, Purchases) {
var activityTab = 'GuideTab';
this.initializeProcess = function (args, scope, model) {
scope.initMaterializedData();
addInternalMethods(scope, model);
};
this.initMaterializedData = function (scope, model) {
model.working = true;
model.edition = {};
model.edition.totalTickets = 0;
model.edition.totalGroupTickets = 0;
model.materializedData = null;
model.showErrors = false;
model.showOptions = false;
model.showTimeSelection = false;
model.showLanguageSelection = false;
model.showBuyButton = false;
model.showAvailableAlone = false;
model.showPriceZero = false;
model.showMinTicketsError = false;
model.showBuyResume = false;
model.showEffect = false;
model.showDateStep = false;
model.showHourStep = false;
model.showOptionsStep = false;
model.showProductGroups = false;
model.currentGroupTitle = null;
model.showIntermediateStep = false;
model.currentOptions = null;
model.requoteWithDate = false;
model.selectedTime = null;
model.selectedLanguage = null;
model.dateNotAvailableMsg = null;
model.availableDates = [];
model.durationTrigger = '';
model.languageTrigger = '';
model.pickup = {
places: []
};
model.showPickupToEnter = false;
model.showPickupSelected = false;
model.showAdditionalData = false;
model.showPickupInputError = false;
model.showPickupDirectiveError = false;
$http.post(CanonicalUrl.getUrl(model.culture, 'purchase-materialized-initial-data-activities-ag'), {
materializedUid: model.currentMaterializedUid,
})
.success(function (data, status, headers, config) {
model.materializedData = data;
if (!data.NotAvailable) {
if (model.materializedData.AskPickup) {
model.allPickupPlaces = [];
$.each(model.materializedData.PickupInformation.PickupAddresses, function (key, val) {
if (val.DisplayName != null) {
model.allPickupPlaces.push({ name: val.DisplayName, id: val.PlaceId })
}
});
if (model.materializedData.PickupInformation.FreePickup == true && model.materializedData.PickupInformation.ListPickup == false) {
model.showPickupToEnter = true;
}
else {
model.showPickupToEnter = false;
}
model.showMaterialEditionTemplatePopUp = true;
model.working = false;
}
else {
scope.loadAdditionalData();
}
}
else {
model.working = false;
model.currentMaterializedUid = null;
model.currentMaterializedType = null;
shApi.handleError(model, data.NotAvailableMsg, false, false);
}
})
.error(function (data, status, headers, config) {
model.working = false;
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
}
this.saveBookingFromMaterialized = function (scope, model) {
model.showingCartIndex = -1;
model.showErrors = false;
if (model.materializedEdition.$valid && model.showBuyButton) {
model.activityNotAvailableMsg = null;
model.working = true;
model.showMaterialEditionTemplatePopUp = false;
$http.post(CanonicalUrl.getUrl(model.culture, 'save-cart-book-from-materialized-activity-ag'), {
materializedUid: model.currentMaterializedUid,
additional: shPurchase.fillAdditionalMaterializedActivity(model),
},
{
headers: {
'__RequestVerificationToken': model.Token
}
})
.success(function (data, status, headers, config) {
model.working = false;
var cartData = JSON.parse(data);
scope.loadGroupedDetails(cartData, model);
scope.closeMaterializedEdition();
model.lastActivityRequestUid = null;
model.currentIndex = null;
model.sliderShow = false;
model.fromBtn = false;
$state.go('add-service-to-cart.activities', { pre: CanonicalUrl.getFolderPrefix(model.culture), targeturl: CanonicalUrl.getCanonicalUrl(model.culture, 'add-service-to-cart/activities'), tab: activityTab, clear: false }).then(function () {
shPurchase.showFloatingCart();
});
})
.error(function (data, status, headers, config) {
model.working = false;
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
}
else {
model.showErrors = true;
model.continue = false;
}
}
this.closeMaterializedEdition = function (scope, model) {
model.showMaterialEditionTemplatePopUp = false;
model.materializedData = null;
model.currentMaterializedType = null;
model.currentMaterializedUid = null;
model.currentOptions = null;
model.showOptions = false;
model.showTimeSelection = false;
model.showBuyResume = false;
model.showBuyButton = false;
model.showAvailableAlone = false;
model.showPriceZero = false;
model.showMinTicketsError = false;
model.edition = null;
model.availableTimes = null;
model.selectedTime = null;
model.selectedLanguage = null;
model.showDateStep = false;
model.showHourStep = false;
model.showOptionsStep = false;
model.showProductGroups = false;
model.currentGroupTitle = null;
model.showIntermediateStep = false;
model.dateNotAvailableMsg = null;
model.showEffect = false;
model.availableDates = [];
//$('.modal-backdrop').remove();
//$('html').css('overflow', 'auto');
$('body').css('padding-right', '');
model.showPickupToEnter = false;
model.showPickupSelected = false;
model.showAdditionalData = false;
model.showPickupInputError = false;
model.showPickupDirectiveError = false;
}
function addInternalMethods(scope, model) {
scope.nextAvailability = function () {
var date = model.edition.dateSvr.toISOString();
model.nextAvailableDates = [];
model.nextAvailableDate = null;
$.each(model.materializedData.AvailabilityCalendar.Dates, function (key, val) {
if (!val.IsSoldOut && (key > date)) {
model.nextAvailableDates.push(key);
return false;
}
});
model.nextAvailableDate = model.nextAvailableDates[0];
}
scope.loadAdditionalData = function () {
model.working = true;
model.selectedPickup = shPurchase.fillAdditionalPickupActivity(model);
$http.post(CanonicalUrl.getUrl(model.culture, 'purchase-materialized-additional-data-activities-ag'), {
materializedUid: model.currentMaterializedUid,
pickup: model.selectedPickup,
currencyCode: model.currencyCode
})
.success(function (data, status, headers, config) {
model.materializedData.NotAvailable = data.NotAvailable;
model.materializedData.NotAvailableMsg = data.NotAvailableMsg;
if (!data.NotAvailable) {
model.materializedData.AskCalendar = data.AskCalendar;
model.materializedData.AskLanguage = data.AskLanguage;
model.materializedData.AvailabilityCalendar = data.AvailabilityCalendar;
model.materializedData.NotAvailableDate = data.NotAvailableDate;
model.materializedData.AskTime = data.AskTime;
model.materializedData.NotAvailableDateMsg = data.NotAvailableDateMsg;
model.materializedData.Options = data.Options;
model.materializedData.DateHourSelected = data.DateHourSelected;
if (model.materializedData.AskCalendar) {
scope.chargeCalendar();
model.edition.dateSvr = model.edition.date != undefined && model.edition.date != null ? shApi.serverUTCDateFromTime(model.edition.date.getTime()) : null;
if (model.materializedData.NotAvailableDate) {
model.dateNotAvailableMsg = data.NotAvailableDateMsg;
scope.nextAvailability();
}
else {
scope.returnToStep('date');
model.dateNotAvailableMsg = null;
scope.loadOptions();
}
}
else {
scope.loadOptions();
}
model.showAdditionalData = true;
}
model.working = false;
if (model.showMaterialEditionTemplatePopUp == false) {
model.showMaterialEditionTemplatePopUp = true;
}
})
.error(function (data, status, headers, config) {
model.working = false;
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
}
scope.loadOptions = function () {
shPurchase.chargeActivityOptions2(model);
if (model.materializedData.AskTime) model.showTimeSelection = true;
if (model.materializedData.AskLanguage) model.showLanguageSelection = true;
if (model.materializedData.AskTime && model.materializedData.AskTime) {
model.selectedTime = model.availableTimes[0];
var langs = shPurchase.loadLanguagesForSelectedTime(model, model.selectedTime.index);
model.selectedLanguage = langs[0];
}
else if (model.materializedData.AskTime && !model.materializedData.AskLanguage) {
model.selectedTime = model.availableTimes[0];
}
else if (!model.materializedData.AskTime && model.materializedData.AskLanguage) {
model.selectedLanguage = model.availableLanguages[0];
}
scope.getGroupsFiltered();
}
scope.$watch('Model.durationTrigger', function (newValue, oldValue) {
if (newValue !== undefined && newValue.length > 0) {
var newVal = newValue.split(':');
if (newVal[0] == 'loadSecondaryValues') {
model.currentLanguageList = shPurchase.loadLanguagesForSelectedTime(model, parseInt(newVal[1]));
}
else if (newVal[0] == 'apply') {
scope.getGroupsFiltered();
}
model.durationTrigger = '';
}
});
scope.$watch('Model.languageTrigger', function (newValue, oldValue) {
if (newValue !== undefined && newValue.length > 0) {
var newVal = newValue.split(':');
if (newVal[0] == 'loadSecondaryValues') {
model.currentTimeList = shPurchase.loadTimesForSelectedLanguage(model, newVal[1]);
}
else if (newVal[0] == 'apply') {
scope.getGroupsFiltered();
}
model.languageTrigger = '';
}
});
scope.getGroupsFiltered = function () {
shPurchase.getGroupsFilteredForActivity(model);
scope.returnToStep('intermediate');
model.showProductGroups = false;
if (Object.keys(model.productGroups).length > 1) {
model.showProductGroups = true;
}
else {
scope.selectGroup(Object.keys(model.productGroups)[0]);
}
}
scope.getAddressesPickup = function (filter) {
return Purchases.getAddressesPickup(filter, model.prefix)
.then(function (response) {
return response;
});
}
scope.showPickupInput = function () {
if (model.pickupPlace) {
model.showPickupToEnter = true;
model.showPickupDirectiveError = false;
model.pickup.places = [];
}
else {
model.showPickupToEnter = false;
model.showPickupInputError = false;
model.edition.pickup = "";
}
}
scope.cleanPickupFields = function () {
model.pickup.places = [];
model.edition.pickup = '';
}
scope.loadCalendar = function () {
var valid = false;
if (model.showPickupToEnter) {
if (model.edition.pickup != undefined && model.edition.pickup.DisplayName != undefined) {
valid = true;
model.materializedEdition.pickup = model.edition.pickup;
model.materializedEdition.pickup.name = model.edition.pickup.DisplayName;
}
else {
model.showPickupInputError = true;
model.showPickupDirectiveError = false;
}
}
else {
if (model.pickup.places.length != 0) {
valid = true;
model.materializedEdition.pickup = model.pickup.places[0];
model.materializedEdition.pickup.name = model.pickup.places[0].name;
}
else {
model.showPickupInputError = false;
model.showPickupDirectiveError = true;
}
}
if (valid) {
model.showPickupInputError = false;
model.showPickupDirectiveError = false;
model.showPickupSelected = true;
scope.loadAdditionalData();
}
else {
model.showPickupSelected = false;
}
}
scope.$watch('Model.edition.pickup', function (newValue, oldValue) {
if (newValue != undefined) {
model.showPickupInputError = false;
}
});
scope.modifyPickup = function () {
model.showAdditionalData = false;
model.showPickupSelected = false
}
scope.selectGroup = function (index) {
model.showEffect = false;
if (index !== undefined) {
$timeout(function () {
shPurchase.selectActivityGroup(model, index);
getTotals();
if (Object.keys(model.productGroups).length > 1) model.showIntermediateStep = true;
model.showBuyResume = true;
model.showOptions = true;
model.showProductGroups = false;
model.showEffect = true;
}, 200);
}
}
scope.deleteOption = function (key) {
shPurchase.deleteActivityOption(model, key);
getTotals();
}
scope.addOption = function (key) {
shPurchase.addActivityOption(model, key);
getTotals();
}
function getTotals() {
shPurchase.getActivityTotals(model);
model.showBuyButton = false;
model.showAvailableAlone = false;
model.showPriceZero = false;
model.showMinTicketsError = false;
if (model.edition.totalTickets >= 1 && !model.edition.hasAvailableAlone) {
model.showAvailableAlone = true;
}
else if (model.edition.totalTickets < model.edition.minBookingTickets) {
model.showMinTicketsError = true;
}
else if (model.edition.totalPrice <= 0 && !model.materializedData.IsFreeTour) {
model.showPriceZero = true;
}
else {
model.showBuyButton = true;
}
}
scope.chargeCalendar = function () {
model.availableDateOptions = shApi.datePickerOptions(model.culture);
model.minDate = shApi.getUTCDateFromString(model.materializedData.AvailabilityCalendar.MinDate);
model.maxDate = shApi.getUTCDateFromString(model.materializedData.AvailabilityCalendar.MaxDate);
//selected date:
var date = shApi.getUTCDateFromString(model.materializedData.DateHourSelected);
model.edition.date = new Date(date.setHours(0, 0, 0, 0));
model.showDateStep = true;
//discard not available days:
model.availableDates = [];
$.each(model.materializedData.AvailabilityCalendar.Dates, function (key, val) {
if (!val.IsSoldOut) {
model.availableDates.push(new Date(key));
}
});
}
scope.updateWithNextDate = function (e) {
model.nextAvailableDateConverted = shApi.getUTCDateFromString(model.nextAvailableDate);
model.edition.dateSvr = model.edition.date = model.nextAvailableDateConverted;
}
scope.disabled = function (date, mode) {
return shPurchase.checkDisabledDates(date, mode, model.availableDates);
};
scope.$watch('Model.edition.date', function (newValue, oldValue) {
//avoid first initialization
var newValDate = newValue != undefined ? newValue.getTime() : newValue;
var oldValDate = oldValue != undefined ? oldValue.getTime() : oldValue;
if (newValue != undefined && newValue != null && oldValue != undefined && newValDate != oldValDate) {
requoteMaterialized();
}
});
function requoteMaterialized() {
model.requoteWithDate = true;
scope.returnToStep('date');
model.edition.dateSvr = model.edition.date != undefined && model.edition.date != null ? shApi.serverUTCDateFromTime(model.edition.date.getTime()) : null;
$http.post(CanonicalUrl.getUrl(model.culture, 'purchase-get-activity-options-ag'), {
materializedUid: model.currentMaterializedUid,
date: model.edition.dateSvr,
currencyCode: model.currencyCode
})
.success(function (data, status, headers, config) {
model.requoteWithDate = false;
if (data != undefined && data != null) {
model.materializedData.Options = data.Options;
model.materializedData.AskLanguage = data.AskLanguage;
model.materializedData.AskTime = data.AskTime;
model.materializedData.NotAvailableDateMsg = data.NotAvailableMsg;
model.materializedData.NotAvailableDate = data.NotAvailable;
if (data.NotAvailable) {
model.dateNotAvailableMsg = data.NotAvailableMsg;
scope.nextAvailability();
}
else {
model.dateNotAvailableMsg = null;
scope.loadOptions();
}
} else {
shApi.handleError(model, data);
}
})
.error(function (data, status, headers, config) {
model.requoteWithDate = false;
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
}
scope.returnToStep = function (step) {
switch (step) {
case 'date':
model.showHourStep = false;
model.showEffect = false;
model.showOptions = false;
model.showTimeSelection = false;
model.showLanguageSelection = false;
model.showBuyResume = false;
model.showBuyButton = false;
model.showAvailableAlone = false;
model.showPriceZero = false;
model.showMinTicketsError = false;
model.availableTimes = null;
model.availableLanguages = null;
model.selectedTime = null;
model.selectLanguage = null;
model.currentOptions = null;
model.currentGroupTitle = null;
model.showIntermediateStep = false;
model.showProductGroups = false;
model.dateNotAvailableMsg = null;
model.edition.options = [];
model.edition.totalPrice = model.edition.totalTickets = 0;
break;
case 'intermediate':
model.showIntermediateStep = false;
model.currentOptions = null;
model.currentGroupTitle = null;
model.showOptions = false;
model.showBuyResume = false;
model.showBuyButton = false;
model.showAvailableAlone = false;
model.showPriceZero = false;
model.showMinTicketsError = false;
model.edition.options = [];
model.edition.totalPrice = model.edition.totalTickets = 0;
model.showProductGroups = true;
model.showEffect = false;
break;
}
}
scope.clearAllData = function () {
model.destinationCity = null;
model.currentMaterializedUid = null;
model.currentMaterializedType = null;
model.materializedList = null;
model.materializedMsg = null;
model.pointOrg = null;
model.pointDest = null;
model.numPeople = 1;
model.date = null;
model.isRoundTrip = false;
model.returnDate = null;
model.minDuration = null;
model.maxDuration = null;
model.detailedPeople = null;
model.activityNotAvailableMsg = null;
scope.closeMaterializedEdition();
}
scope.addPickupPlace = function (place, pickup) {
model.pickup.places.push(place);
if (model.pickup.places.length > 1) {
model.pickup.places.splice(0, 1);
}
};
scope.removePickupPlace = function (place, pickup) {
var idx = model.pickup.places.indexOf(place);
model.pickup.places.splice(idx, 1);
};
};
});
})();
(function () {
'use strict';
//TODO: Limpiar todo
var ngPurchasesService = angular.module('ngPurchasesService');
ngPurchasesService.service('BookingConfigGroundHourlyStandard', function (CanonicalUrl, $http, shApi, $state, $cookies, $timeout, Validations, $sce, $window, Translator, shPurchase, Purchases) {
this.initializeProcess = function (args, scope, model) {
scope.initMaterializedData();
addInternalMethods(scope, model);
};
this.initMaterializedData = function (scope, model) {
model.edition = {};
model.edition.meetingPoint = [];
model.edition.notesForProvider = null;
model.materializedData = null;
model.working = true;
model.meetingPointErrorMsg = [];
model.baggageEdition = {};
if (model.anonymousPhoneCode != undefined)
model.baggageEdition.anonymousPhoneCode = model.anonymousPhoneCode;
model.maxBaggageAreaLength = 500;
model.orgStage = null;
model.blockContinue = model.recalculatePrice = false;
model.showIconList = false;
$http.post(CanonicalUrl.getUrl(model.culture, 'purchase-materialized-data-driver-by-hours-ag'), {
materializedUid: model.currentMaterializedUid,
currencyCode: model.currencyCode
})
.success(function (data, status, headers, config) {
model.materializedData = data;
shPurchase.initializeMaterializedDataGroundHourly(model, data, true);
model.baggageContacted = false;
model.showMaterialEditionTemplatePopUp = true;
$('#bck-img').css("background-image", "url(" + model.materializedData.ImgUrl + ")");
model.working = false;
})
.error(function (data, status, headers, config) {
model.working = false;
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
};
this.closeMaterializedEdition = function (scope, model) {
model.showMaterialEditionTemplatePopUp = false;
model.edition = null;
model.materializedData = null;
model.showIconList = false;
model.currentMaterializedType = null;
model.currentMaterializedUid = null;
//$('.modal-backdrop').remove();
//$('html').css('overflow', 'auto');
shPurchase.cleanMeetingPointFormErrors(model);
}
this.saveBookingFromMaterialized = function (scope, model) {
if (model.materializedEdition.$valid) {
var p = shPurchase.fillAdditionalMaterializedData(model.edition, true, model.currencyCode);
model.working = true;
model.showMaterialEditionTemplatePopUp = false;
$http.post(CanonicalUrl.getUrl(model.culture, 'save-cart-book-from-materialized-ground-ag'), {
materializedUid: model.currentMaterializedUid,
additional: p
})
.success(function (data, status, headers, config) {
model.working = false;
var cartData = JSON.parse(data);
scope.loadGroupedDetails(cartData, model);
scope.closeMaterializedEdition();
shPurchase.showFloatingCart();
})
.error(function (data, status, headers, config) {
model.working = false;
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
}
else {
model.continue = false;
}
}
function addInternalMethods(scope, model) {
scope.animation = function () {
$("#details").toggleClass('transition-transfer');
}
scope.$watch('Model.edition.totalBaggage', function (newValue, oldValue) {
if (newValue != undefined && newValue != null && newValue != oldValue) {
shPurchase.checkBaggageValidity(model.edition, model.edition.numServices, model.edition.numBaggageItems);
}
});
scope.$watch('Model.edition.meetingPoint', function (newVal, oldVal) {
if (newVal != oldVal && newVal != undefined) {
//Preparado para cuando haya m�s de un posible pto de edici�n
//shPurchase.meetingPointMaterializedValidity(model, 'purchase-check-meeting-point-materialized-ag', newVal, oldVal, model.currentMaterializedUid, model.rqType, null);
}
}, true);
scope.getMeetingPointAddresses = function (filter) {
return Purchases.getMeetingPointAddressesCart(filter, model.prefix, model.materializedData.InfoBag.MeetingPointLimits.Coordinates.Latitude, model.materializedData.InfoBag.MeetingPointLimits.Coordinates.Longitude, model.materializedData.InfoBag.MeetingPointLimits.Radious).then(function (response) {
return response;
});
};
scope.baggageContactSend = function () {
if (model.userPurchaseCart.$valid) {
model.working = true;
var c = model.baggageEdition;
$http.post(CanonicalUrl.getUrl(model.culture, 'purchase-baggage-contact-ag'), {
materializedUid: model.currentMaterializedUid,
email: c.anonymousEmail,
name: c.anonymousName,
phoneCode: c.anonymousPhoneCode,
phone: c.anonymousPhone,
notes: c.anonymousMsg
}).success(function (data, status, headers, config) {
model.working = false;
model.baggageContacted = true;
if (data != 'true') {
shApi.handleError(model, data, true);
}
//scope.closeMaterializedEdition();
}).error(function (data, status, headers, config) {
model.working = false;
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
}
else
model.continue = false;
};
scope.clearAllData = function() {
model.destinationCity = null;
model.currentMaterializedUid = null;
model.currentMaterializedType = null;
model.materializedList = null;
model.materializedMsg = null;
model.pointOrg = null;
model.pointDest = null;
model.numPeople = 1;
model.date = null;
model.isRoundTrip = false;
model.returnDate = null;
model.minDuration = null;
model.maxDuration = null;
model.detailedPeople = null;
scope.closeMaterializedEdition();
}
}
});
})();
(function () {
'use strict';
//TODO: Limpiar todo
var ngPurchasesService = angular.module('ngPurchasesService');
ngPurchasesService.service('BookingConfigGroundRouteStandard', function (CanonicalUrl, $http, shApi, $state, $cookies, $timeout, Validations, $sce, $window, Translator, shPurchase, Purchases) {
this.initializeProcess = function (args, scope, model) {
scope.initMaterializedData();
addInternalMethods(scope, model);
};
this.initMaterializedData = function (scope, model) {
model.working = true;
model.edition = {};
model.edition.flightNumberOrigin1 = null;
model.edition.flightNumberDestination1 = null;
model.edition.flightNumberOrigin2 = null;
model.edition.flightNumberDestination2 = null;
model.notAvailableMsg = null;
model.edition.notesForProvider = null;
model.materializedData = null;
model.working = true;
model.baggageEdition = {};
if (model.anonymousPhoneCode != undefined)
model.baggageEdition.anonymousPhoneCode = model.anonymousPhoneCode;
model.maxBaggageAreaLength = 500;
model.orgStage = null;
model.destStage = null;
model.blockContinue = model.recalculatePrice = false;
model.showPickupRequiredError = false;
model.flightNumberFromList1 = model.flightNumberFromList2 =
model.flightNumberCoincidence1 = model.flightNumberCoincidence2 =
model.destinationFlightDateWrongCheck1 = model.destinationFlightDateWrongCheck2 =
model.originFlightDateWrongCheck1 = model.originFlightDateWrongCheck2 =
model.destinationFlightErrorCoincidence1 = model.destinationFlightErrorCoincidence2 = false;
model.originFlightErrorCoincidence1 = model.originFlightErrorCoincidence2 = false;
model.pickupDateCheckGreater = model.pickupDateCheckReturnGreater = false;
model.pickupDateCheckMinor = model.pickupDateCheckReturnMinor = false;
model.chargeMap = true;
model.showMap = false;
model.showIconList = false;
model.flightInfoDestination1 = model.flightInfoDestination2 =
model.flightInfoOrigin1 = model.flightInfoOrigin2 = null;
model.showFlightConfirmationOrigin1 = model.showFlightConfirmationOrigin2 =
model.showFlightConfirmationDestination1 = model.showFlightConfirmationDestination2 = false;
model.showPickupCalendar = false;
model.errorTimeBeforeArrival = false;
model.warningArrivalPickupTime = false;
model.errorAfterDepartureTime = false;
model.warningDeparturePickupTime = false;
model.calendarDate = null;
model.providerDate = null;
model.durationBeforeDeparture = null;
model.originDate = null;
model.recommendedDateBeforeDeparture = null;
model.flightNumberEntered = false;
model.errorInCalendar = false;
model.showPoliciesMessageGroundRoute = false;
model.showPickup1 = model.showPickup2 = false;
model.loadingPickup1 = model.loadingPickup2 = false;
model.waitToChoosePickup = true;
model.oneWaySelected = false;
model.returnSelected = false;
model.showAdditional = false;
model.callCount = 0;
model.userSelectedPickupDate = model.userSelectedPickupHour = null;
model.pickupDate = model.pickupReturnDate = null;
model.showErrorModal = false;
$http.post(CanonicalUrl.getUrl(model.culture, 'purchase-materialized-data-route-ag'), {
materializedUid: model.currentMaterializedUid,
currencyCode: model.currencyCode
})
.success(function (data, status, headers, config) {
model.materializedData = data;
shPurchase.initializeMaterializedDataGroundRoute(model, data);
shPurchase.initDefaultBaggage(model);
model.baggageContacted = false;
if ((model.orgStage.FlightNumberOrigin || model.orgStage.FlightNumberDestination)
|| (model.destStage != undefined && model.destStage != null && (model.destStage.FlightNumberOrigin || model.destStage.FlightNumberDestination)))
model.showAdditional = false;
else
model.showAdditional = true;
model.working = false;
model.showMaterialEditionTemplatePopUp = true;
})
.error(function (data, status, headers, config) {
model.working = false;
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
}
this.closeMaterializedEdition = function (scope, model) {
model.showMaterialEditionTemplatePopUp = false;
model.edition = null;
model.materializedData = null;
model.baggageEdition = null;
model.baggageContacted = false;
model.chargeMap = true;
model.showMap = false;
model.showIconList = false;
model.currentMaterializedType = null;
model.currentMaterializedUid = null;
model.notAvailableMsg = null;
//$('.modal-backdrop').remove();
//$('html').css('overflow', 'auto');
shPurchase.cleanFlightFormErrors(model);
scope.cleanPickupErrors();
model.showErrorModal = false;
}
this.saveBookingFromMaterialized = function (scope, model) {
shPurchase.validateCheckFlightOneWay(model);
shPurchase.validateCheckFlightReturn(model);
if (model.showFlightConfirmationOrigin1 == true || model.showFlightConfirmationDestination1 == true) {
if (model.materializedEdition.pickupSelected.$viewValue == "pickup1" || model.materializedEdition.pickupSelected.$viewValue == "pickup2") {
model.showPickupRequiredError = false;
}
else {
model.showPickupRequiredError = true;
}
}
if (model.showFlightConfirmationOrigin2 == true || model.showFlightConfirmationDestination2 == true) {
if (model.materializedEdition.pickupReturnSelected.$viewValue == "pickupReturn1" || model.materializedEdition.pickupReturnSelected.$viewValue == "pickupReturn2") {
model.showPickupReturnRequiredError = false;
}
else {
model.showPickupReturnRequiredError = true;
}
}
model.showingCartIndex = -1;
if (model.materializedEdition.$valid && !model.showPickupRequiredError && !model.showPickupReturnRequiredError && !model.errorTimeBeforeArrival && !model.errorAfterDepartureTime &&
!model.errorReturnTimeBeforeArrival && !model.errorAfterDepartureReturnTime) {
var p = shPurchase.fillAdditionalMaterializedData(model.edition, true, model.currencyCode);
model.working = true;
model.showMaterialEditionTemplatePopUp = false;
$http.post(CanonicalUrl.getUrl(model.culture, 'save-cart-book-from-materialized-ground-ag'), {
materializedUid: model.currentMaterializedUid,
additional: p
})
.success(function (data, status, headers, config) {
model.working = false;
var cartData = JSON.parse(data);
scope.loadGroupedDetails(cartData, model);
scope.closeMaterializedEdition();
model.showingMoreDeals = -1;
$("body").removeClass("overflow-consolidator");
$("html").removeClass("overflow-consolidator");
shPurchase.showFloatingCart();
})
.error(function (data, status, headers, config) {
model.working = false;
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
shApi.scrollToTop();
}
}
function addInternalMethods(scope, model) {
scope.$watch('Model.edition.totalBaggage', function (newValue, oldValue) {
if (newValue != undefined && newValue != null && newValue != oldValue) {
shPurchase.checkBaggageValidity(model.edition, model.edition.numServices, model.edition.numBaggageItems);
}
});
scope.baggageContactSend = function () {
if (model.userPurchaseCart.$valid) {
model.working = true;
var c = model.baggageEdition;
$http.post(CanonicalUrl.getUrl(model.culture, 'purchase-baggage-contact-ag'), {
materializedUid: model.currentMaterializedUid,
email: c.anonymousEmail,
name: c.anonymousName,
phoneCode: c.anonymousPhoneCode,
phone: c.anonymousPhone,
notes: c.anonymousMsg
}).success(function (data, status, headers, config) {
model.working = false;
model.baggageContacted = true;
if (data != 'true') {
shApi.handleError(model, data, true);
}
//scope.closeMaterializedEdition();
}).error(function (data, status, headers, config) {
model.working = false;
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
}
else
model.continue = false;
};
//M�todos principales del flujo:
scope.saveOneWayData = function (e) {
if (shApi.preventNavigate(e)) return;
//1. Validation:
shPurchase.validateCheckFlightOneWay(model);
if (model.showFlightConfirmationOrigin1 == true || model.showFlightConfirmationDestination1 == true) {
if (model.materializedEdition.pickupSelected.$viewValue == "pickup1" || model.materializedEdition.pickupSelected.$viewValue == "pickup2") {
model.showPickupRequiredError = false;
}
else {
model.showPickupRequiredError = true;
}
}
//2. Continuaci�n a siguiente paso
if ((model.orgStage.FlightNumberOrigin && !model.materializedEdition.flightNumberOrigin1.$valid) ||
(model.orgStage.FlightNumberDestination && !model.materializedEdition.flightNumberDestination1.$valid) ||
model.showPickupRequiredError || model.errorTimeBeforeArrival || model.errorAfterDepartureTime) {
model.continue = true;
}
else {
model.continue = false;
model.oneWaySelected = true;
if (model.destStage != undefined && model.destStage != null && (model.destStage.FlightNumberOrigin || model.destStage.FlightNumberDestination)) {
model.showAdditional = false;
}
else {
model.showAdditional = true;
}
}
};
scope.returnToOneWayData = function (e) {
if (shApi.preventNavigate(e)) return;
model.oneWaySelected = false;
model.returnSelected = false;
model.showAdditional = false;
};
scope.saveReturnData = function (e) {
if (shApi.preventNavigate(e)) return;
if (shApi.preventNavigate(e)) return;
//1. Validation:
shPurchase.validateCheckFlightReturn(model);
if (model.showFlightConfirmationOrigin2 == true || model.showFlightConfirmationDestination2 == true) {
if (model.materializedEdition.pickupReturnSelected.$viewValue == "pickupReturn1" || model.materializedEdition.pickupReturnSelected.$viewValue == "pickupReturn2") {
model.showPickupReturnRequiredError = false;
}
else {
model.showPickupReturnRequiredError = true;
}
}
//2. Continuaci�n a siguiente paso
if ((model.destStage.FlightNumberOrigin && !model.materializedEdition.flightNumberOrigin2.$valid) ||
(model.destStage.FlightNumberDestination && !model.materializedEdition.flightNumberDestination2.$valid) ||
model.showPickupReturnRequiredError || model.errorReturnTimeBeforeArrival || model.errorAfterDepartureReturnTime) {
model.continue = true;
}
else {
model.continue = false;
model.returnSelected = true;
model.showAdditional = true;
}
}
scope.returnToReturnData = function (e) {
if (shApi.preventNavigate(e)) return;
model.returnSelected = false;
model.showAdditional = false;
}
scope.checkPickupErrors = function (date, hour) {
//Control de errores
model.errorInCalendar = false;
model.calendarDate = shApi.getCompleteDateHour(date, hour, 0);
model.providerDate = shApi.getUTCDateFromString(model.orgStage.ProviderDateService);
//Llegada aeropuerto
if (model.orgStage.FlightNumberOrigin == true && model.orgStage.FlightNumberDestination == false) {
if (model.calendarDate < model.edition.flightDateOrigin1) {
model.errorTimeBeforeArrival = true;
model.errorInCalendar = true;
model.warningArrivalPickupTime = false;
}
else if (model.edition.flightDateOrigin1 <= model.calendarDate && model.calendarDate < model.providerDate) {
model.warningArrivalPickupTime = true;
model.errorTimeBeforeArrival = false;
}
else {
model.errorTimeBeforeArrival = false;
model.warningArrivalPickupTime = false;
}
}
////Salida aeropuerto
else if (model.orgStage.FlightNumberOrigin == false && model.orgStage.FlightNumberDestination == true) {
model.durationBeforeDeparture = new Date(model.edition.flightDateDestination1.getTime() - (model.orgStage.JourneyDuration.Units * 60 * 60 * 1000));
if (model.durationBeforeDeparture <= model.calendarDate) {
model.errorAfterDepartureTime = true;
model.warningDeparturePickupTime = false;
model.errorInCalendar = true;
}
else if (model.calendarDate > model.providerDate && model.calendarDate <= model.durationBeforeDeparture) {
model.warningDeparturePickupTime = true;
model.errorAfterDepartureTime = false;
}
else {
model.errorAfterDepartureTime = false;
model.warningDeparturePickupTime = false;
}
}
//Aeropuerto-aeropuerto
else if (model.orgStage.FlightNumberOrigin == true && model.orgStage.FlightNumberDestination == true) {
model.durationBeforeDeparture = new Date(model.edition.flightDateDestination1.getTime() - (model.orgStage.JourneyDuration.Units * 60 * 60 * 1000));
model.recommendedDateBeforeDeparture = new Date(model.edition.flightDateDestination1.getTime() - (3 * 60 * 60 * 1000));
if (model.durationBeforeDeparture <= model.calendarDate) {
model.errorAfterDepartureTime = true;
model.warningDeparturePickupTime = false;
model.warningArrivalPickupTime = false;
model.errorTimeBeforeArrival = false;
model.errorInCalendar = true;
}
else if (model.calendarDate > model.recommendedDateBeforeDeparture && model.calendarDate <= model.durationBeforeDeparture) {
model.warningDeparturePickupTime = true;
model.errorAfterDepartureTime = false;
model.warningArrivalPickupTime = false;
model.errorTimeBeforeArrival = false;
}
else if (model.calendarDate <= model.edition.flightDateOrigin1) {
model.errorTimeBeforeArrival = true;
model.warningArrivalPickupTime = false;
model.errorAfterDepartureTime = false;
model.warningDeparturePickupTime = false;
model.errorInCalendar = true;
}
else if (model.edition.flightDateOrigin1 <= model.calendarDate && model.calendarDate < model.providerDate) {
model.warningArrivalPickupTime = true;
model.errorTimeBeforeArrival = false;
model.errorAfterDepartureTime = false;
model.warningDeparturePickupTime = false;
}
else {
model.errorTimeBeforeArrival = false;
model.errorAfterDepartureTime = false;
model.warningDeparturePickupTime = false;
model.warningArrivalPickupTime = false;
}
}
}
//Pickup para la vuelta
scope.changePickupReturnTime = function (pickupReturnDate) {
if (model.edition != undefined) {
model.indicatedPickupReturnDate = shApi.getCompleteDateHour(model.edition.returnDateService, model.edition.returnHourService, 0);
model.edition.returnDate = model.indicatedPickupReturnDate;
scope.validateDate(model.edition.returnDate, model.edition.returnDate, model.minServiceReturnDate, model.maxServiceReturnDate, model.materializedEdition.returnDate);
if (model.materializedEdition.returnDate.$valid) {
requoteMaterialized("returnDate");
}
document.getElementById("pickupReturn2").click();
model.showPickupReturnCalendar = false;
}
//Control de errores
scope.checkPickupReturnErrors();
}
scope.checkPickupReturnErrors = function () {
//Control de errores
model.errorInReturnCalendar = false;
model.calendarReturnDate = shApi.getCompleteDateHour(model.edition.returnDateService, model.edition.returnHourService, 0);
//Llegada aeropuerto
if (model.destStage.FlightNumberOrigin == true && model.destStage.FlightNumberDestination == false) {
if (model.calendarReturnDate < model.edition.flightDateOrigin2) {
model.errorReturnTimeBeforeArrival = true;
model.errorInReturnCalendar = true;
model.warningArrivalPickupReturnTime = false;
}
else if (model.edition.flightDateOrigin2 <= model.calendarReturnDate && model.calendarReturnDate < model.edition.returnProviderDate) {
model.warningArrivalPickupReturnTime = true;
model.errorReturnTimeBeforeArrival = false;
}
else {
model.errorReturnTimeBeforeArrival = false;
model.warningArrivalPickupReturnTime = false;
}
}
////Salida aeropuerto
else if (model.destStage.FlightNumberOrigin == false && model.destStage.FlightNumberDestination == true) {
model.durationBeforeReturnDeparture = new Date(model.edition.flightDateDestination2.getTime() - (model.destStage.JourneyDuration.Units * 60 * 60 * 1000));
if (model.durationBeforeReturnDeparture <= model.calendarReturnDate) {
model.errorAfterDepartureReturnTime = true;
model.warningDeparturePickupReturnTime = false;
model.errorInReturnCalendar = true;
}
else if (model.calendarReturnDate > model.edition.returnProviderDate && model.calendarReturnDate <= model.durationBeforeReturnDeparture) {
model.warningDeparturePickupReturnTime = true;
model.errorAfterDepartureReturnTime = false;
}
else {
model.errorAfterDepartureReturnTime = false;
model.warningDeparturePickupReturnTime = false;
}
}
//Aeropuerto-aeropuerto
else if (model.destStage.FlightNumberOrigin == true && model.destStage.FlightNumberDestination == true) {
model.durationBeforeReturnDeparture = new Date(model.edition.flightDateDestination2.getTime() - (model.destStage.JourneyDuration.Units * 60 * 60 * 1000));
model.recommendedReturnDateBeforeDeparture = new Date(model.edition.flightDateDestination2.getTime() - (3 * 60 * 60 * 1000));
if (model.durationBeforeReturnDeparture <= model.calendarReturnDate) {
model.errorAfterDepartureReturnTime = true;
model.warningDeparturePickupReturnTime = false;
model.warningArrivalPickupReturnTime = false;
model.errorReturnTimeBeforeArrival = false;
model.errorInReturnCalendar = true;
}
else if (model.calendarReturnDate > model.recommendedReturnDateBeforeDeparture && model.calendarReturnDate <= model.durationBeforeReturnDeparture) {
model.warningDeparturePickupReturnTime = true;
model.errorAfterDepartureReturnTime = false;
model.warningArrivalPickupReturnTime = false;
model.errorReturnTimeBeforeArrival = false;
}
else if (model.calendarReturnDate <= model.edition.flightDateOrigin2) {
model.errorReturnTimeBeforeArrival = true;
model.warningArrivalPickupReturnTime = false;
model.errorAfterDepartureReturnTime = false;
model.warningDeparturePickupReturnTime = false;
model.errorInReturnCalendar = true;
}
else if (model.edition.flightDateOrigin2 <= model.calendarReturnDate && model.calendarReturnDate < model.edition.returnProviderDate) {
model.warningArrivalPickupReturnTime = true;
model.errorReturnTimeBeforeArrival = false;
model.errorAfterDepartureReturnTime = false;
model.warningDeparturePickupReturnTime = false;
}
else {
model.errorReturnTimeBeforeArrival = false;
model.errorAfterDepartureReturnTime = false;
model.warningDeparturePickupReturnTime = false;
model.warningArrivalPickupReturnTime = false;
}
}
}
scope.cleanPickupErrors = function () {
model.errorAfterDepartureTime = false;
model.warningDeparturePickupTime = false;
model.warningArrivalPickupTime = false;
model.errorTimeBeforeArrival = false;
model.showPickupRequiredError = false;
model.calendarDate = null;
model.providerDate = null;
model.durationBeforeDeparture = null;
model.originDate = null;
model.recommendedDateBeforeDeparture = null;
model.errorAfterDepartureReturnTime = false;
model.warningDeparturePickupReturnTime = false;
model.warningArrivalPickupReturnTime = false;
model.errorReturnTimeBeforeArrival = false;
model.showPickupReturnRequiredError = false;
model.calendarReturnDate = null;
model.providerReturnDate = null;
model.durationBeforeReturnDeparture = null;
model.originReturnDate = null;
model.recommendedReturnDateBeforeDeparture = null;
}
scope.initMap = function () {
if (model.chargeMap) {
//Initialize map
var org = model.orgStage.StageInfo.Origin;
var dest = model.orgStage.StageInfo.Destination;
shPurchase.showGoogleRouteMap(org.Latitude, org.Longitude, dest.Latitude, dest.Longitude);
model.showMap = true;
}
}
scope.hideMap = function () {
model.chargeMap = true;
model.showMap = false;
}
scope.getFlightInfoOrigin1 = function () {
model.materializedEdition.flightNumberOrigin1.$setValidity("valEmptyField", true);
model.materializedEdition.flightNumberOrigin1.$setValidity('valDateWrong', true);
model.materializedEdition.flightNumberOrigin1.$setValidity('valErrorCoincidence', true);
if ((model.materializedEdition.flightNumberOrigin1.$error.pattern == undefined) && (model.materializedEdition.flightNumberOrigin1.$error.required == undefined)) {
model.flightNumberEntered = true;
var flight = model.edition.flightNumberOrigin1;
var dateArr = model.edition.date;
var iataDestination = model.orgStage.StageInfo.Origin.AirportCode;
model.showFlightConfirmationOrigin1 = false;
model.flightNumberOrigin1Loading = true;
model.recalculatePrice = true;
Purchases.getFlightInfo(flight, null, dateArr, model.prefix, null, iataDestination)
.then(function (response) {
model.recalculatePrice = false;
model.flightNumberOrigin1Loading = false;
if (response == undefined || response.Error) {
model.materializedEdition.flightNumberOrigin1.$setValidity('valDateWrong', false);
}
else {
model.materializedEdition.flightNumberOrigin1.$setValidity('valDateWrong', true);
model.flightSelected = undefined;
var totalFlights = 0; var formatedHours = 0; model.hourFormated = {}; model.typeOfFlihtManual = 1; model.isStandard = true;
totalFlights = response.Flights.length;
model.flightsList = response.Flights;
model.typeOfFlight = "FlightInfoOrigin1";
if (totalFlights > 1) {
do {
model.hourFormated[formatedHours] = shApi.getUTCDateFromString(model.flightsList[formatedHours].ArrivalDate);
formatedHours++;
}
while (formatedHours < totalFlights);
model.modalFlightSelector = true;
}
else {
scope.flightAfterModal(model.typeOfFlight,0);
}
}
});
}
else {
model.continue = true;
}
}
scope.getFlightInfoDestination1 = function () {
model.materializedEdition.flightNumberDestination1.$setValidity("valEmptyField", true);
model.materializedEdition.flightNumberDestination1.$setValidity('valDateWrong', true);
model.materializedEdition.flightNumberDestination1.$setValidity('valErrorCoincidence', true);
if ((model.materializedEdition.flightNumberDestination1.$error.pattern == undefined) && (model.materializedEdition.flightNumberDestination1.$error.required == undefined)) {
model.flightNumberEntered = true;
var flight = model.edition.flightNumberDestination1;
var date = model.edition.date;
var iataOrigin = model.orgStage.StageInfo.Destination.AirportCode;
model.showFlightConfirmationDestination1 = false;
model.flightNumberDestination1Loading = true;
model.recalculatePrice = true;
Purchases.getFlightInfo(flight, date, null, model.prefix, iataOrigin, null)
.then(function (response) {
model.recalculatePrice = false;
model.flightNumberDestination1Loading = false;
if (response == undefined || response.Error) {
model.materializedEdition.flightNumberDestination1.$setValidity('valDateWrong', false);
}
else {
model.materializedEdition.flightNumberDestination1.$setValidity('valDateWrong', true);
model.flightSelected = undefined;
var totalFlights = 0; var formatedHours = 0; model.hourFormated = {}; model.typeOfFlihtManual = 2; model.isStandard = true;
totalFlights = response.Flights.length;
model.flightsList = response.Flights;
model.typeOfFlight = "FlightInfoDestination1";
if (totalFlights > 1) {
do {
model.hourFormated[formatedHours] = shApi.getUTCDateFromString(model.flightsList[formatedHours].DepartureDate);
formatedHours++;
}
while (formatedHours < totalFlights);
model.modalFlightSelector = true;
}
else {
scope.flightAfterModal(model.typeOfFlight, 0);
}
}
});
}
else {
model.continue = true;
}
}
scope.getFlightInfoOrigin2 = function () {
model.materializedEdition.flightNumberOrigin2.$setValidity("valEmptyField", true);
model.materializedEdition.flightNumberOrigin2.$setValidity('valDateWrong', true);
model.materializedEdition.flightNumberOrigin2.$setValidity('valErrorCoincidence', true);
if ((model.materializedEdition.flightNumberOrigin2.$error.pattern == undefined) && (model.materializedEdition.flightNumberOrigin2.$error.required == undefined)) {
var flight = model.edition.flightNumberOrigin2;
var dateArr = model.edition.returnDate;
var iataDestination = model.destStage.StageInfo.Origin.AirportCode;
model.showFlightConfirmationOrigin2 = false;
model.flightInfoOrigin2 = null;
model.flightNumberOrigin2Loading = true;
model.recalculatePrice = true;
Purchases.getFlightInfo(flight, null, dateArr, model.prefix, null, iataDestination)
.then(function (response) {
model.recalculatePrice = false;
model.flightNumberOrigin2Loading = false;
if (response == undefined || response.Error) {
model.materializedEdition.flightNumberOrigin2.$setValidity('valDateWrong', false);
}
else {
model.flightSelected = undefined;
var totalFlights = 0; var formatedHours = 0; model.hourFormated = {}; model.typeOfFlihtManual = 3; model.isStandard = true;
totalFlights = response.Flights.length;
model.flightsList = response.Flights;
model.typeOfFlight = "FlightInfoOrigin2";
if (totalFlights > 1) {
do {
model.hourFormated[formatedHours] = shApi.getUTCDateFromString(model.flightsList[formatedHours].ArrivalDate);
formatedHours++;
}
while (formatedHours < totalFlights);
model.modalFlightSelector = true;
}
else {
scope.flightAfterModal(model.typeOfFlight, 0);
}
}
});
}
else {
model.continue = true;
}
}
scope.getFlightInfoDestination2 = function () {
model.materializedEdition.flightNumberDestination2.$setValidity("valEmptyField", true);
model.materializedEdition.flightNumberDestination2.$setValidity('valDateWrong', true);
model.materializedEdition.flightNumberDestination2.$setValidity('valErrorCoincidence', true);
if ((model.materializedEdition.flightNumberDestination2.$error.pattern == undefined) && (model.materializedEdition.flightNumberDestination2.$error.required == undefined)) {
var flight = model.edition.flightNumberDestination2;
var date = model.edition.returnDate;
var iataOrigin = model.destStage.StageInfo.Destination.AirportCode;
model.showFlightConfirmationDestination2 = false;
model.flightInfoDestination2 = null;
model.flightNumberDestination2Loading = true;
model.recalculatePrice = true;
Purchases.getFlightInfo(flight, date, null, model.prefix, iataOrigin, null)
.then(function (response) {
model.recalculatePrice = false;
model.flightNumberDestination2Loading = false;
if (response == undefined || response.Error) {
model.materializedEdition.flightNumberDestination2.$setValidity('valDateWrong', false);
}
else {
model.flightSelected = undefined;
var totalFlights = 0; var formatedHours = 0; model.hourFormated = {}; model.typeOfFlihtManual = 4; model.isStandard = true;
totalFlights = response.Flights.length;
model.flightsList = response.Flights;
model.typeOfFlight = "FlightInfoDestination2";
if (totalFlights > 1) {
do {
model.hourFormated[formatedHours] = shApi.getUTCDateFromString(model.flightsList[formatedHours].DepartureDate);
formatedHours++;
}
while (formatedHours < totalFlights);
model.modalFlightSelector = true;
}
else {
scope.flightAfterModal(model.typeOfFlight, 0);
}
}
});
}
else {
model.continue = true;
}
}
scope.flightAfterModal = function (ftype, fselected) {
if (ftype == "FlightInfoOrigin1" && fselected >= 0) {
var response = model.flightsList[fselected];
model.flightInfoOrigin1 = response;
var originCode = model.orgStage.StageInfo.Origin.AirportCode;
if (originCode != null) {
if (originCode != response.IATADestination) {
model.materializedEdition.flightNumberOrigin1.$setValidity('valErrorCoincidence', false);
}
else {
//Si hay aeropuerto destino
model.showFlightConfirmationOrigin1 = true;
model.materializedEdition.flightNumberOrigin1.$setValidity('valErrorCoincidence', true);
model.edition.flightDateOrigin1 = shApi.getUTCDateFromString(response.ArrivalDate);
model.edition.departuredateflightOrigin1 = shApi.getUTCDateFromString(response.DepartureDate);
model.edition.arrivaldateflightOrigin1 = shApi.getUTCDateFromString(response.ArrivalDate);
shPurchase.checkShowPickup(model, false, true);
requoteMaterialized("flightDate");
}
}
model.edition.flightNumberOrigin1 = response.FlightCode;
model.modalFlightSelector = false;
}
if (ftype == "FlightInfoDestination1" && fselected >= 0) {
var response = model.flightsList[fselected];
model.flightInfoDestination1 = response;
var destCode = model.orgStage.StageInfo.Destination.AirportCode;
if (destCode != null) {
if (destCode != response.IATAOrigin) {
model.materializedEdition.flightNumberDestination1.$setValidity('valErrorCoincidence', false);
}
else {
//Si hay aeropuerto destino
model.showFlightConfirmationDestination1 = true;
model.materializedEdition.flightNumberDestination1.$setValidity('valErrorCoincidence', true);
model.edition.flightDateDestination1 = shApi.getUTCDateFromString(response.DepartureDate);
model.edition.departuredateflightDestination1 = shApi.getUTCDateFromString(response.DepartureDate);
model.edition.arrivaldateflightDestination1 = shApi.getUTCDateFromString(response.ArrivalDate);
shPurchase.checkShowPickup(model, false, true);
requoteMaterialized("flightDate");
}
}
model.edition.flightNumberDestination1 = response.FlightCode;
model.modalFlightSelector = false;
}
if (ftype == "FlightInfoOrigin2" && fselected >= 0) {
var response = model.flightsList[fselected];
model.flightInfoOrigin2 = response;
model.materializedEdition.flightNumberOrigin2.$setValidity('valDateWrong', true);
var originCode = model.destStage.StageInfo.Origin.AirportCode;
if (originCode != null) {
if (originCode != response.IATADestination) {
model.materializedEdition.flightNumberOrigin2.$setValidity('valErrorCoincidence', false);
}
else {
//Si hay aeropuerto destino
model.showFlightConfirmationOrigin2 = true;
model.materializedEdition.flightNumberOrigin2.$setValidity('valErrorCoincidence', true);
model.edition.flightDateOrigin2 = shApi.getUTCDateFromString(response.ArrivalDate);
model.edition.departuredateflightOrigin2 = shApi.getUTCDateFromString(response.DepartureDate);
model.edition.arrivaldateflightOrigin2 = shApi.getUTCDateFromString(response.ArrivalDate);
shPurchase.checkShowPickup(model, true, true);
requoteMaterialized("flightDateReturn");
}
}
model.edition.flightNumberOrigin2 = response.FlightCode;
model.modalFlightSelector = false;
}
if (ftype == "FlightInfoDestination2" && fselected >= 0) {
var response = model.flightsList[fselected];
model.flightInfoDestination2 = response;
model.materializedEdition.flightNumberDestination2.$setValidity('valDateWrong', true);
var destCode = model.destStage.StageInfo.Destination.AirportCode;
if (destCode != null) {
if (destCode != response.IATAOrigin) {
model.materializedEdition.flightNumberDestination2.$setValidity('valErrorCoincidence', false);
}
else {
//Si hay aeropuerto destino
model.showFlightConfirmationDestination2 = true;
model.materializedEdition.flightNumberDestination2.$setValidity('valErrorCoincidence', true);
model.edition.flightDateDestination2 = shApi.getUTCDateFromString(response.DepartureDate);
model.edition.departuredateflightDestination2 = shApi.getUTCDateFromString(response.DepartureDate);
model.edition.arrivaldateflightDestination2 = shApi.getUTCDateFromString(response.ArrivalDate);
shPurchase.checkShowPickup(model, true, true);
requoteMaterialized("flightDateReturn");
}
}
model.edition.flightNumberDestination2 = response.FlightCode;
model.modalFlightSelector = false;
}
if (fselected == "FlightManual") {
model.modalFlightSelector = false;
model.isFlightManualEdition = true;
}
}
scope.flightChange = function (newVal, oldVal, form) {
if (newVal != oldVal) {
form.$setValidity('valDateWrong', true);
form.$setValidity('valErrorCoincidence', true);
form.$setValidity('valEmptyField', true);
}
};
scope.$watch('Model.pickupDate', function (newVal, oldVal) {
if (newVal != oldVal && newVal != undefined && newVal != null) {
if (newVal == 'pickup1') {
model.edition.date = model.edition.providerDate;
requoteMaterialized("date");
}
else if (newVal == 'pickup2') {
model.edition.date = model.indicatedPickupDate;
scope.checkPickupErrors(model.edition.date, model.edition.date);
if (model.errorTimeBeforeArrival == false && model.errorAfterDepartureTime == false) {
requoteMaterialized("date");
}
}
}
});
scope.$watch('Model.pickupReturnDate', function (newVal, oldVal) {
if (newVal != oldVal && newVal != undefined && newVal != null) {
if (newVal == 'pickupReturn1') {
model.edition.returnDate = model.edition.providerReturnDate;
requoteMaterialized("returnDate");
}
else if (newVal == 'pickupReturn2') {
model.edition.returnDate = model.indicatedPickupReturnDate;
scope.checkPickupReturnErrors();
if (model.errorReturnTimeBeforeArrival == false && model.errorAfterDepartureReturnTime == false) {
requoteMaterialized("returnDate");
}
}
}
});
function dateServicePickupCheck() {
model.pickupDateCheckGreater = false;
model.pickupDateCheckMinor = false;
//Si no sale de un aeropuerto, evaluar fecha de destino
if (!model.orgStage.FlightNumberOrigin && model.orgStage.FlightNumberDestination && (model.edition.date > model.edition.providerDate)) {
model.pickupDateCheckGreater = true;
}
else if (model.orgStage.FlightNumberOrigin && (model.edition.date < model.edition.providerDate)) {
model.pickupDateCheckMinor = true;
}
}
function returnDateServicePickupCheck() {
if (model.destStage != undefined && model.destStage != null) {
model.pickupDateCheckReturnGreater = false;
model.pickupDateCheckReturnMinor = false;
if (!model.destStage.FlightNumberOrigin && model.destStage.FlightNumberDestination && (model.edition.returnDate > model.edition.returnProviderDate)) {
model.pickupDateCheckReturnGreater = true;
}
else if (model.destStage.FlightNumberOrigin && (model.edition.returnDate < model.edition.returnProviderDate)) {
model.pickupDateCheckReturnMinor = true;
}
}
}
scope.editFlight = function (e, n) {
if (shApi.preventNavigate(e)) return;
switch (n) {
case 1:
model.showFlightConfirmationOrigin1 = false;
model.showPickup1 = false;
model.pickupDate = null;
break;
case 2:
model.showFlightConfirmationDestination1 = false;
model.showPickup1 = false;
model.pickupDate = null;
break;
case 3:
model.showFlightConfirmationOrigin2 = false;
model.showPickup2 = false;
model.pickupReturnDate = null;
break;
case 4:
model.showFlightConfirmationDestination2 = false;
model.showPickup2 = false;
model.pickupReturnDate = null;
break;
}
}
//Modal pickup
scope.openModalChangePickupTime = function (e) {
model.userSelectedPickupDate = model.userSelectedPickupHour = model.edition.date;
//Saltar� el watcher
model.showPickupCalendar = true;
}
scope.changePickupTime = function () {
scope.validateDate(model.userSelectedPickupDate, model.userSelectedPickupHour, model.minServiceDate, model.maxServiceDate, model.materializedEdition.userPickupDate);
scope.checkPickupErrors(model.userSelectedPickupDate, model.userSelectedPickupHour);
if (model.materializedEdition.userPickupDate.$valid && !model.errorTimeBeforeArrival && !model.errorAfterDepartureTime) {
model.indicatedPickupDate = shApi.getCompleteDateHour(model.userSelectedPickupDate, model.userSelectedPickupHour, 0);
model.edition.date = model.indicatedPickupDate;
requoteMaterialized("date");
document.getElementById("pickup2").click();
model.showPickupCalendar = false;
model.userSelectedPickupDate = model.userSelectedPickupHour = null;
}
}
scope.closePickupModal = function () {
model.showPickupCalendar = false;
model.userSelectedPickupDate = model.userSelectedPickupHour = null;
scope.checkPickupErrors(model.edition.date, model.edition.date);
}
scope.$watch('Model.userSelectedPickupDate', function (newVal, oldVal) {
if (newVal != oldVal && newVal != undefined && newVal != null) {
scope.validateDate(model.userSelectedPickupDate, model.userSelectedPickupHour, model.minServiceDate, model.maxServiceDate, model.materializedEdition.userPickupDate);
scope.checkPickupErrors(newVal, model.userSelectedPickupHour);
}
});
scope.$watch('Model.userSelectedPickupHour', function (newVal, oldVal) {
if (newVal != oldVal && newVal != undefined && newVal != null) {
scope.validateDate(model.userSelectedPickupDate, model.userSelectedPickupHour, model.minServiceDate, model.maxServiceDate, model.materializedEdition.userPickupDate);
scope.checkPickupErrors(model.userSelectedPickupDate, newVal);
}
});
function requoteMaterialized(rqType) {
model.edition.calculatingPickup1 = false;
model.edition.calculatingPickup2 = false;
model.edition.userDateMandatory = true;
model.edition.returnUserDateMandatory = true;
if (rqType != undefined) {
if (rqType == "date") {
model.recalculateWithPickupDate = true;
}
else if (rqType == "returnDate") {
model.recalculateWithReturnPickupDate = true;
}
else if (rqType == "flightDate") {
model.edition.userDateMandatory = true;
}
else if (rqType == "flightDateReturn") {
model.edition.returnUserDateMandatory = true;
}
}
model.showErrorModal = false;
model.blockContinue = true; //Block continue button during price recalculation
model.recalculatePrice = true;
var p = shPurchase.fillAdditionalMaterializedData(model.edition, true, model.currencyCode);
model.notAvailableMsg = null;
var countNumber = ++model.callCount;
//model.working = true;
$http.post(CanonicalUrl.getUrl(model.culture, 'purchase-recalculate-materialized-route-ag'), {
materializedUid: model.currentMaterializedUid,
additional: p
})
.success(function (data, status, headers, config) {
if (countNumber == model.callCount) { //discard old petitions
model.recalculatePrice = false;
if (data != undefined && data != null) {
if (data.NotAvailable) {
model.notAvailableMsg = data.NotAvailableMsg;
model.showErrorModal = true;
}
else {
model.notAvailableMsg = null;
model.showErrorModal = false;
model.materializedData = data;
shPurchase.initializeMaterializedDataGroundRoute(model, data);
model.blockContinue = false;
model.requoted = true;
dateServicePickupCheck();
returnDateServicePickupCheck();
if (rqType == "flightDate") {
model.indicatedPickupDate = shApi.getUTCDateFromString(model.orgStage.DateHour);
}
else if (rqType == "flightDateReturn") {
model.indicatedPickupReturnDate = shApi.getUTCDateFromString(model.destStage.DateHour);
}
}
} else {
shApi.handleError(model, data);
}
}
if (rqType == "date") {
model.recalculateWithPickupDate = false;
}
else if (rqType == "returnDate") {
model.recalculateWithReturnPickupDate = false;
}
else if (rqType == "flightDate") {
model.loadingPickup1 = false;
}
else if (rqType == "flightDateReturn") {
model.loadingPickup2 = false;
}
})
.error(function (data, status, headers, config) {
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
}
scope.clearAllData = function() {
model.reload = false;
model.destinationCity = null;
model.currentMaterializedUid = null;
model.currentMaterializedType = null;
model.materializedList = null;
model.materializedMsg = null;
model.pointOrg = null;
model.pointDest = null;
model.numPeople = 1;
model.date = null;
model.isRoundTrip = false;
model.returnDate = null;
model.minDuration = null;
model.maxDuration = null;
model.detailedPeople = null;
scope.closeMaterializedEdition();
}
scope.animation = function () {
$("#details").toggleClass('transition-transfer');
}
};
});
})();
(function() {
'use strict';
var ngPurchasesService = angular.module('ngPurchasesService');
ngPurchasesService.service('CartStandard', function (CanonicalUrl, $http, shApi, $state, shPurchase, Purchases, $timeout, Translator) {
var mi = null;
this.initializeProcess = function(args, scope, model) {
mi = model;
model.showEditRevision = false;
model.maxBaggageAreaLength = 500;
model.dataUpdating = null;
model.showDiscount = false;
model.firstStep = false;
model.secondStep = true;
model.showingIndex = -1;
model.showingCartIndex = -1;
model.participantsNeeded = false;
model.hasActivities = false;
scope.internalRefreshCartData(true, model, scope);
}
this.deleteServiceBooking = function (args, scope, model) {
var returnUrl;
var serviceGroup = args[0];
var index = args[1];
trackAnalyticsEvent('ProCom', 'PPAC', 'Booking deleted from cart');
model.working = true;
$http.post(CanonicalUrl.getUrl(model.culture, 'delete-service-from-cart-ag'), {
serviceGroup: serviceGroup,
}).success(function (data, status, headers, config) {
model.working = false;
if (data === "true") {
model.cartDetail.details.splice(index, 1);
scope.internalRefreshCartData(true, model, scope);
model.deletingIndex = -1;
model.ShowPurchaseConfirm = false;
} else {
shApi.handleError(model, data);
}
}).error(function (data, status, headers, config) {
model.working = false;
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
}
this.deleteAllServices = function (e, model, scope) {
var token = $('input[name="__RequestVerificationToken"]').val();
model.working = true;
$http.post(CanonicalUrl.getUrl(model.culture, 'delete-all-service-from-cart-ag'), {
}
, {
headers: {
'__RequestVerificationToken': token
}
})
.success(function (data, status, headers, config) {
model.working = false;
model.cartDetail = null;
scope.internalRefreshCartData(true, model, scope);
model.showConfirmPanel = false;
model.comeFromConfirmPanel = true;
shApi.scrollToTop();
})
.error(function (data, status, headers, config) {
model.working = false;
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
}
this.applyDiscountByCode = function(scope, model) {
var token = $('form[name="Model.userPurchaseCart"] input[name="__RequestVerificationToken"]').val();
if (model.discountCode != null && model.discountCode.length > 0 && model.discountCode != 'undefined') {
model.working = true;
trackAnalyticsEvent('ProCom', 'PPAC', 'Discount code applied: ' + model.discountCode);
$http.post(CanonicalUrl.getUrl(model.culture, 'cart-apply-discount-ag'), {
discountCode: model.discountCode,
}, {
headers: {
'__RequestVerificationToken': token
}
}).success(function(data, status, headers, config) {
model.working = false;
if (data != null && typeof data.discount != 'undefined') {
model.cartDetail.discount = data.discount;
model.cartDetail.summary.finalTotal = data.finalTotal;
model.cartDetail.summary.finalAsignment = data.finalAsignment;
model.cartDetail.dollar.finalTotal = data.finalTotalDollar;
model.cartDetail.dollar.finalAsignment = data.finalAsignmentDollar;
model.showDiscount = false;
} else {
model.errordiscount = data;
}
}).error(function(data, status, headers, config) {
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
}
}
});
})();
(function() {
'use strict';
var ngPurchasesService = angular.module('ngPurchasesService');
ngPurchasesService.service('CheckoutStandard', function (CanonicalUrl, $http, shApi, $state, shPurchase, shCheckout, Purchases, $timeout, Translator, Validations, $cookies, $sce, $window) {
var $qtimer = null;
this.initializeProcess = function (args, scope, model) {
$window.stepFirst = model.stepFirst = false;
model.stepSecond = true;
var headerBeforeCart = document.getElementById('headerBeforeCart');
if (headerBeforeCart != null) headerBeforeCart.classList.add("hidden");
var headerAfterCart = document.getElementById('headerAfterCart');
if (headerAfterCart != null) headerAfterCart.classList.remove("hidden")
model.showCheckOutContainer = true;
model.showLogin = false;
model.client = {};
model.binding = false;
model.pageError = null;
model.remember = true;
model.showAlerts = {};
//model.errordiscount = null;
//model.paymentMethods = args[1];
//model.mainDirectPayment = args[2];
//model.mainDirectPaymentIntegration = args[3];
model.summary = {};
model.summary.guid = args[4];
model.mainError = false;
model.noShowLoginForm = false;
//model.integrationTypeAuxiliar = args[5];
model.alternativePayments = false;
model.continue = false;
model.paymentButtons = [];
model.showingIndex = -1;
model.showingPoliciesIndex = -1;
model.showTravellerData = -1;
model.showTravellerDataSaved = -1;
model.newData = false;
window.onbeforeunload = null;
model.showClientInfo = false;
model.showClientEmailAlert = false;
model.notEdit = false;
model.showFirstStep = false;
model.showFirstStepResume = false;
model.showSecondStep = false;
model.showSecondStepResume = false;
model.participantSelectorOpen = [];
addInternalMethods(scope, model);
//1.Check if user is logged
scope.initClientData();
scope.internalRefreshCartData(true, model, scope);
model.firstLoadTimeClient = false;
model.loadingClientEmail = false;
model.formMessages = args[6];
$('header').removeClass("big");
$('.integration-body').removeClass("integration-body--no-margin");
//Evitar aterrizaje con fondo d carrito
$('html').removeClass('delete-scroll');
$('body').removeClass('delete-scroll');
}
this.ConfirmClientLogin = function (scope, model, e, fromRegister) {
model.pageError = null;
model.continue = true;
if (typeof e != 'undefined' && e != null && shApi.preventNavigate(e, model)) return;
if (typeof fromRegister == 'undefined') fromRegister = false;
var token = $('form[name="Model.clientLogin"] input[name="__RequestVerificationToken"]').val();
if (model.clientLogin.$valid || fromRegister) {
model.working = true;
$http.post(CanonicalUrl.getUrl(model.culture, 'cart-login-ag'), {
email: model.client.email,
password: model.password,
remember: model.remember,
}
, {
headers: {
'__RequestVerificationToken': token
}
})
.success(function (data, status, headers, config) {
model.working = false;
//parse data
if (data.client != undefined && data.discountData != undefined) {
scope.parseClientData(parseClientInfo(data.client));
model.password = '';
model.clientLogin.$setUntouched();
model.showLoginRegister = false;
if (model.clientLoggedIn) scope.copyClientToBuyerForm();
model.mainTravellerCheck = null;
model.showClientEmailAlert = false;
if (!model.hasActivities) {
scope.noActivitiesNextStep();
}
}
else {
model.incorrectLoginData = true;
model.errorLoginMsg = data;
}
})
.error(function (data, status, headers, config) {
model.password = '';
model.clientLogin.$setUntouched();
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
} else {
model.formClientData.$setUntouched();
model.continue = true;
}
}
function parseClientInfo(client) {
var newClient = {};
newClient.Email = client.email;
newClient.Name = client.name;
newClient.Surname = client.surname;
newClient.MainPhone = client.mainPhone;
newClient.IsValid = client.isValid;
newClient.IsNewClient = client.isNewClient;
return newClient;
}
function addInternalMethods(scope, model) {
scope.initClientData = function () {
model.working = true;
$http.post(CanonicalUrl.getUrl(model.culture, 'client-data-logged-ag'), {})
.success(function (data, status, headers, config) {
scope.parseClientData(data);
if (model.clientLoggedIn) {
scope.copyClientToBuyerForm();
model.showClientEmailAlert = false;
}
//Must check if user is logged in
scope.initTravellersData();
})
.error(function (data, status, headers, config) {
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, true);
model.working = false;
});
};
scope.accountLogout = function (e) {
if (e != undefined && shApi.preventNavigate(e, model)) return;
model.notEdit = false;
model.working = true;
//model.alternativePayments = false;
//Verifica si est� loggeado y en caso de estarlo hace logout
if (model.clientLoggedIn) {
$http.post(CanonicalUrl.getUrl(model.culture, 'cart-checkout-logout-ag'))
.success(function (data, status, headers, config) {
if (data.client != undefined) {
scope.parseClientData(parseClientInfo(data.client));
scope.copyClientToBuyerForm();
model.password = '';
shCheckout.goToStep(1, model);
}
model.working = false;
})
.error(function (data, status, headers, config) {
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, false);
});
}
};
scope.editFirstStep = function (e) {
if (e != undefined) if (shApi.preventNavigate(e, model)) return;
shCheckout.editFirstStep(model);
if (!model.hasActivities && !model.clientLoggedIn) model.showBuyerForm = true;
}
scope.goToFirstStep = function (e) {
if (e != undefined) if (shApi.preventNavigate(e, model)) return;
shCheckout.goToStep(1, model);
}
scope.editSecondStep = function (e) {
if (e != undefined) if (shApi.preventNavigate(e, model)) return;
shCheckout.goToStep(2, model);
}
scope.showServiceDetails = function (e, id) {
model.showingDetailsIndex = id;
model.showingPoliciesIndex = -1;
}
scope.showPolicies = function (e, id) {
model.showingPoliciesIndex = id;
model.showingDetailsIndex = -1;
}
scope.addNewTraveller = function (e) {
if (e != undefined) if (shApi.preventNavigate(e, model)) return;
shCheckout.addNewTraveller(scope, model, model.anonymousPhoneCode != undefined ? model.anonymousPhoneCode : null);
}
scope.deleteTraveller = function (e, travellerId) {
if (e != undefined) if (shApi.preventNavigate(e, model)) return;
delete model.travellerInformation[travellerId];
}
scope.clearTravellerData = function (e, travellerId) {
if (e != undefined) if (shApi.preventNavigate(e, model)) return;
shCheckout.clearTravellerData(scope, model, travellerId, model.anonymousPhoneCode != undefined ? model.anonymousPhoneCode : null);
}
scope.saveTravellerData = function (e, index, travellerId) {
if (e !== undefined) if (shApi.preventNavigate(e, model)) return;
shCheckout.saveTravellerData(model, index, travellerId);
if (model.travellerInformation[travellerId].mainTraveller && model.mainTravellerCheck) {
if (model.travellerInformation[travellerId].valid) {
fillBuyerDataWithTravellerData();
}
else {
shCheckout.clearBuyerData(model, model.anonymousPhoneCode != undefined ? model.anonymousPhoneCode : null);
}
}
};
scope.closeTravellerData = function (index, travellerId) {
model.travellerInformation[travellerId].valid = !shCheckout.checkIfTravellerFormsAreInvalid(model, travellerId, index);
if (model.travellerInformation[travellerId].mainTraveller && model.mainTravellerCheck) {
if (model.travellerInformation[travellerId].valid) {
fillBuyerDataWithTravellerData();
}
else {
shCheckout.clearBuyerData(model, model.anonymousPhoneCode != undefined ? model.anonymousPhoneCode : null);
}
}
model.showTravellerData = -1;
}
scope.saveAllTravellers = function (e) {
if (e !== undefined) if (shApi.preventNavigate(e, model)) return;
model.showTravellerData = -1;
model.showTravellerErrors = false;
var index = 0;
var valid = true;
var pendingCompletion = false;
//Check buyer
if (!(model.clientLoggedIn || (model.formBuyerData.$valid && !model.showClientEmailAlert))) {
valid = false;
}
//Check travellers
if (valid && model.hasActivities) {
$.each(model.travellerInformation, function (key, val) {
if (shCheckout.checkIfTravellerFormsAreInvalid(model, key, index)) {
valid = false;
return;
}
index++;
});
}
if (valid) {
//Data by
model.showFirstStep = false;
model.showFirstStepResume = true;
if (model.hasActivities && model.participantsNeeded) {
shCheckout.tryMatchTravellersWithSlotAuto(scope, model);
model.showSecondStep = true;
model.showSecondStepResume = false;
shApi.scrollTo('#card-participants', 1000, 200);
}
else {
model.showFinalButton = true;
shApi.scrollTo('#card-prices', 1000);
}
}
else {
model.showTravellerErrors = true;
}
};
scope.selectParticipant = function (e, activityKey, slotKey, participantIndex, travellerKey, btnId) {
if (e !== undefined) if (shApi.preventNavigate(e, model)) return;
shCheckout.selectParticipant(model, activityKey, slotKey, participantIndex, travellerKey, btnId);
};
scope.saveParticipants = function (e) {
if (e !== undefined) if (shApi.preventNavigate(e, model)) return;
var valid = shCheckout.saveParticipants(model);
if (valid) {
shApi.scrollTo('#card-prices', 1000);
}
};
scope.initTravellersData = function () {
var token = $('input[name="__RequestVerificationToken"]').val();
model.working = true;
$http.get(CanonicalUrl.getUrl(scope.Model.culture, 'purchase-user-travellers-data-ag'),
{
},
{
headers: {
'__RequestVerificationToken': token
}
})
.success(function (data, status, headers, config) {
model.participantsNeeded = data.askParticipantsInfo;
model.hasActivities = data.hasActivities;
model.travellerNumberCalculated = data.travellerNumberCalculated;
if (model.hasActivities) {
model.participantQuestions = data.participantQuestions;
if (!model.clientLoggedIn) {
model.mainTravellerCheck = true;
}
else {
model.mainTravellerCheck = null;
}
shCheckout.initializeActivityList(model, data.activityList);
}
scope.initTravellersStep();
model.working = false;
})
.error(function (data, status, headers, config) {
shApi.handleError(model, Translator.getTranslation('modal_error_text'), false, true);
model.working = false;
});
};
scope.clientFirstTime = function (e) {
if (shApi.preventNavigate(e, model)) return;
model.client = {};
model.continue = false;
model.showLoginRegister = true;
model.existingEmail = false;
model.showLogin = true;
model.pageError = null;
model.mainError = false;
model.registrationError = false;
model.password = '';
if (model.buyerData != undefined && model.buyerData != null) {
model.client.email = angular.copy(model.buyerData.email);
}
};
scope.convertCartAndPay = function (e) {
var registerClient = angular.copy(model.buyerData);
registerClient.isNew = !model.clientLoggedIn;
model.working = true;
var travellersData = null;
var activityTravellers = null;
if (model.hasActivities) {
//Clean and match traveller data
travellersData = shCheckout.getTravellersDataFormattedToUpload(model);
if (model.participantsNeeded) {
activityTravellers = shCheckout.getActivityTravellersMatchedFormattedToUpload(model);
}
}
$http.post(CanonicalUrl.getUrl(scope.Model.culture, 'cart-get-payment-link-ag'), {
clientData: registerClient,
travellersData: travellersData,
activityTravellers: activityTravellers,
})
.success(function (data, status, headers, config) {
if (data != null && data != undefined && data != null && data != '') {
model.convertedCart = true;
$window.location.href = data;
}
else {
shApi.handleError(model, data);
//model.working = false;
}
})
.error(function (data, status, headers, config) {
model.working = false;
model.pageError = data.messageError;
model.convertedCart = false;
});
}
//Travellers step
scope.initTravellersStep = function () {
model.notEdit = false;
if (model.hasActivities) {
model.participantsBirthDateMax = new Date();
model.participantsBirthDateCenter = new Date();
model.participantsBirthDateCenter.setFullYear(model.participantsBirthDateCenter.getFullYear() - 25);
model.participantsBirthDateMin = new Date();
model.participantsBirthDateMin.setFullYear(model.participantsBirthDateMin.getFullYear() - 120); //edad maxima 120 años
shCheckout.initTravellers(scope, model, model.travellerNumberCalculated, model.anonymousPhoneCode != undefined ? model.anonymousPhoneCode : null);
if (!model.clientLoggedIn) model.mainTravellerCheck = true;
model.showFirstStep = true;
}
else {
scope.noActivitiesNextStep();
}
}
scope.noActivitiesNextStep = function () {
if (model.clientLoggedIn) {
model.showFirstStep = false;
model.showFirstStepResume = true;
model.notEdit = true;
model.showFinalButton = true;
}
else {
model.showBuyerForm = true;
model.showFirstStep = true;
}
}
scope.parseClientData = function (data) {
//Logged client
model.clientLoggedIn = data.IsValid;
if (data.Name !== null && data.Name !== '') {
var fullName = data.Name;
if (data.Surname !== null) fullName += ' ' + data.Surname;
model.loggedClientName = fullName;
}
else
model.loggedClientName = '';
model.clientEmail = data.Email;
model.clientName = data.Name;
model.clientSurname = data.Surname;
model.clientPhone = data.MainPhone;
model.isNewClient = data.IsNewClient;
};
scope.copyClientToBuyerForm = function () {
model.buyerData = {};
model.buyerData.email = model.clientEmail;
model.buyerData.name = model.clientName;
model.buyerData.surname = model.clientSurname;
model.buyerData.phoneCode = null;
model.buyerData.phone = null;
var phone = model.clientPhone;
if (phone != null && phone.split('-').length == 2) {
model.buyerData.phoneCode = phone.split('-')[0];
model.buyerData.phone = phone.split('-')[1];
}
};
scope.closeBuyerData = function () {
model.showBuyerForm = false;
if (model.formBuyerData.$valid) {
checkIfFilledEmailExists();
}
};
scope.saveBuyerData = function (e) {
if (shApi.preventNavigate(e, scope.Model)) return;
if (model.formBuyerData.$valid) {
model.showBuyerForm = false;
checkIfFilledEmailExists();
model.continue = false;
}
else {
model.continue = true;
}
};
scope.clearBuyerData = function (e) {
if (shApi.preventNavigate(e, scope.Model)) return;
shCheckout.clearBuyerData(model, model.anonymousPhoneCode != undefined ? model.anonymousPhoneCode : null);
}
scope.$watch('Model.mainTravellerCheck', function (newVal, oldVal) {
if (newVal != oldVal && newVal != undefined && newVal != null) {
if (newVal) {
if (model.travellerInformation[model.mainTravellerId].valid) {
fillBuyerDataWithTravellerData();
}
model.showBuyerForm = false;
}
else {
shCheckout.clearBuyerData(model, model.anonymousPhoneCode != undefined ? model.anonymousPhoneCode : null);
model.showBuyerForm = true;
model.showClientEmailAlert = false;
}
shCheckout.setParticipantTravellerCustomer(model, newVal);
}
});
$(function() {
if (window.history && window.history.pushState) {
$(window).on('popstate', function() {
location.replace("/add-service-to-cart");
});
}
});
function fillBuyerDataWithTravellerData() {
model.showClientEmailAlert = false;
Validations.existsClientEmail(model.travellerInformation[model.mainTravellerId].email, scope.Model.prefix).then(function (response) {
if (response.raw == true) {
model.showClientEmailAlert = true;
}
shCheckout.fillBuyerDataWithTravellerData(model);
});
}
function checkIfFilledEmailExists() {
Validations.existsClientEmail(model.buyerData.email, scope.Model.prefix).then(function (response) {
if (response.raw == true)
model.showClientEmailAlert = true;
else {
model.showClientEmailAlert = false;
if (!model.hasActivities) {
scope.saveAllTravellers();
}
}
});
}
};
});
})();
/*
* File: servantripIframeCommunications.js
* Desc: Include this file in page that loads an iframe
* to establish bidirectional communication.
* And alseo include it on content page loaded
* Warning:
* PostMessage requires * as targetOrigin to be able to comunicate in different domains
* This message may be intercepted by a malicious third party. NEVER Pass Passwords with targetOrigin ="*"
*
*/
/**
* Message type on communication
* */
var MessageType =
{
Resize: 'RESIZE',
Text: 'TEXT'
};
/**
*Coomunication message data
* @param {any} senderId
* @param {any} messageType
*/
function CommunicationMessage(senderId, messageType) {
this.senderId = senderId,
this.messageType = messageType;
};
function NewHeightMessage(senderId, newHeight, collapsing) {
CommunicationMessage.call(this, senderId, MessageType.Resize);
this.newHeight = newHeight;
this.collapsing = collapsing;
}
function SimpleTextMessage(senderId, messageType, text) {
CommunicationMessage.call(this, senderId, MessageType.Text);
this.text = text;
}
/**
* Singleton object to establsih communications
* */
var CommunicationBridge = (function () {
// Instance stores a reference to the Singleton
var mainInstance;
return {
// Get the Singleton instance if one exists
// or create one if it doesn't
getInstance: function (options) {
if (!mainInstance) {
if (!options) {
console.error('No options defined trying to enter CommunicationBridgeMethod');
}
mainInstance = new IframeCommunicationBridge(options);
}
return mainInstance;
}
};
})();
var IframeCommunicationBridge = function (opt) {
//var instance;
this.id = "ParentWindow";
//Check is ifrmaeElement to assign id
var frameEl = window.frameElement;
if (frameEl) {
//In iframe
this.id = frameEl.id;
}
this.prefix = "CHILD";
// See warning on top
//this.targetOrigin = location.href;
this.targetOrigin = "*";
this.logEnabled = false;
this.options = {};
this.options.autoAdjustIframe = false;
this.options.increaseSize = 30;
this.options.parent = false;
if (opt) {
this.options = opt;
this.logEnabled = this.options.logEnabled;
if (this.options.parent == true) {
this.prefix = "PARENT";
}
if (opt.id) {
this.id = opt.id;
}
//Callback de recepción de mensaje
if (this.options.onMessageCallback) {
this.onMessageReceived = this.options.onMessageCallback;
}
}
this.initListen();
};
/**
* Traces app
* @param {any} msg
*/
IframeCommunicationBridge.prototype.log = function (msg) {
if (this.logEnabled) {
console.log('[' + this.prefix + ']' + '[' + this.id + ']' + msg);
}
};
IframeCommunicationBridge.prototype.onMessageReceived = function (msg) {
this.log('onMessageReceived not handled');
};
/**
* Attach message processing callback
* @param {function(data:{CommunicationMessage})} func
*/
IframeCommunicationBridge.prototype.attachMessageCalback = function (func) {
this.log('Attaching MessageCalback ');
this.onMessageReceived = func;
};
/**
* Callback function that notifies subscribers
* @param {any} data
*/
IframeCommunicationBridge.prototype.listener = function (msg) {
window.CommunicationBridge.getInstance().log("Recieved on listener ");
if (msg.data.messageType == MessageType.Resize) {
window.CommunicationBridge.getInstance().autoAdjustIframeSize(msg.data);
}
window.CommunicationBridge.getInstance().onMessageReceived(msg.data);
};
IframeCommunicationBridge.prototype.autoAdjustIframeSize = function (msg) {
if (msg.messageType == MessageType.Resize) {
var opt = window.CommunicationBridge.getInstance().options;
if (opt.autoAdjustIframe == true) {
var iframeElement = document.getElementById(msg.senderId);
var height = msg.newHeight;
if (opt.increaseSize) {
height += opt.increaseSize;
}
if (iframeElement) {
iframeElement.height = height;
}
}
}
}
/**
* Establish event listener
* */
IframeCommunicationBridge.prototype.initListen = function () {
this.log(" on initListen");
window.addEventListener('message', this.listener, false);
};
/**
* Sends text message to the indicated iframe
* @param {string} msg
* @param {string} iframeId
*/
IframeCommunicationBridge.prototype.sendMessageToChild = function (msg, iframeId) {
this.log('Sending Message To Child:' + msg);
var textMessage = new SimpleTextMessage(this.id, msg);
var iframeDst = document.getElementById(iframeId).contentWindow;
iframeDst.postMessage(textMessage, this.targetOrigin);
};
/**
* Sends resize event to the host of the iframe, indicates if is collapsing now
* @param {any} collapsing
*/
IframeCommunicationBridge.prototype.sendResizeToParent = function (collapsing) {
this.log('Sending Resize To Parent');
var message = new NewHeightMessage(this.id, document.body.scrollHeight, collapsing);
window.parent.postMessage(message, this.targetOrigin);
};
/**
* Sends text message to the to the host of the iframe
* @param {string} msg
*/
IframeCommunicationBridge.prototype.sendMessageToParent = function (msg) {
this.log('Sending Message To Parent');
var textMessage = new SimpleTextMessage(this.id, msg);
window.parent.postMessage(textMessage, this.targetOrigin);
};
IframeCommunicationBridge.prototype.onMessageReceived = function (msg) {
this.log('Message :' + msg + ' was received callback not assigned');
};
//Use on parent
var communicationsBridge;
$(document).ready(function () {
var options = {
parent: true,
log: false, // Enable console logging
autoAdjustIframe: true,
onResized: function (messageData) {
},
onMessageCallback: function (messageData) {
// console.log("OnMessageCallback :sender:[ " + messageData.senderId + "], type[ " + messageData.messageType + "],height[ " + messageData.newHeight + "]");
// $("#iframe1").height(messageData.newHeight);
}
};
communicationsBridge = new CommunicationBridge.getInstance(options);
//To send message to child do:
//communicationsBridge.sendMessageToChild("text to send ", 'iframe1');
});
//Use on child iframe
/*
var communicationsBridge;
$(document).ready(function () {
//En un hijo
var options = {
parent: false,
log: true, // Enable console logging
onMessageCallback: function (messageData) {
console.log("EMBEBBED "+messageData.text);
}
};
communicationsBridge = CommunicationBridge.getInstance(options);
var collapsing=true;
communicationsBridge.sendResizeToParent(collapsing);
//Sends another message
communicationsBridge.sendMessageToParent("Message");
});
*/
/*!
* Bootstrap Timepicker
* @author Amir Hussain
**/
var bstptid = '';
var defaultMinuteStep = 1;
var defaultHeaderText = "Select Time";
var defaultApplyText = "Apply";
!function (t, i) {
"function" == typeof define && define.amd ? define(["jquery"], i) : "object" == typeof exports ? module.exports = i(require("jquery")) : t.$ = i(t.jQuery)
}(this, function (t) {
"use strict";
var i = function (t) {
return t >= 10 ? t + "" : "0" + t
}, e = /^[0-9]{1,2}:[0-9]{1,2}$/, s = {}, n = function () {
}, o = new Array(24).fill(null).map(function (t, e) {
var s = i(e);
return '' + s + " "
}).join(""), c = new Array(12).fill(null).map(function (t, e) {
var s = i(5 * e);
return '' + s + " "
}).join(""),
l = t('\t\t
\t\t\t
\t\t\t\t
\t\t\t\t\t
\t\t\t\t\t
\t\t\t\t\t
\t\t\t\t
\t\t\t\t
\t\t\t\t\t
\t\t\t\t\t
:
\t\t\t\t\t
\t\t\t\t
\t\t\t\t
\t\t\t\t\t
\t\t\t\t\t
\t\t\t\t\t
\t\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t
\t ');
return l.find("a").attr("href", "javascript:void(0);"), s.content = l, s.title = l.find(".title"), s.applyBtn = l.find(".js-save-button"), s.mobileTitle = l.find(".base-selector__header-title"), s.choseAll = l.find(".chose-all"), s.choseMinute = l.find(".chose-minute"), s.choseHour = l.find(".chose-hour"), s.hourShow = l.find(".js-hour-show"), s.minuteShow = l.find(".js-minute-show"), s.update = function () {
return bstptid.val(i(this.hour) + ":" + i(this.minute)), this.minuteShow.text(i(this.minute)), this.hourShow.text(i(this.hour)), this.inputTarget.$timepickerUpdate(), this
}, s.bindEvent = function () {
var t = this;
t.hasBind || (t.hasBind = !0, this.content.on("click", ".js-minus-minute", function () {
t.minute = t.minute - t.minuteStep;
if (t.minute < 0) {
t.minute = t.minute + 60;
}
t.update();
}).on("click", ".js-plus-minute", function () {
t.minute = t.minute + t.minuteStep;
if (t.minute >= 60) {
t.minute = t.minute - 60;
}
t.update();
}).on("click", ".js-plus-houer", function () {
t.hour >= 23 ? t.hour = 0 : t.hour++, t.update()
}).on("click", ".js-minus-houer", function () {
t.hour <= 0 ? t.hour = 23 : t.hour--, t.update()
}).on("click", ".js-minute-cell", function () {
t.minute = +this.getAttribute("data-val"), t.update(), t.choseMinute.hide(), t.choseAll.show(), t.title.text(t.headerText)
}).on("click", ".js-hour-cell", function () {
t.hour = +this.getAttribute("data-val"), t.update(), t.choseHour.hide(), t.choseAll.show(), t.title.text(t.headerText)
}).on("click", function (t) {
t.stopPropagation()
}), t.hourShow.on("click", function () {
t.choseAll.hide(), t.choseHour.show(), t.title.text(t.headerText)
}), t.minuteShow.on("click", function () {
t.choseAll.hide(), t.choseMinute.show(), t.title.text(t.headerText)
}))
}, t.timepicker = s, t.fn.timepicker = function (i) {
t.timepicker.minuteStep = i.minuteStep !== undefined ? i.minuteStep : defaultMinuteStep;
t.timepicker.headerText = i.headerText !== undefined ? i.headerText : defaultHeaderText;
t.timepicker.applyText = i.applyText !== undefined ? i.applyText : defaultApplyText;
if (this[0].nodeName && "INPUT" === this[0].nodeName) return this.$timepickerUpdate = n, this.off("keydown").on("keydown", function () {
return !1
}), this.update = function (i) {
t.isFunction(i) ? this.$timepickerUpdate = i : this.$timepickerUpdate = n
}, this
}, t.fn.showTimepicker = function (i) {
this.$timepickerUpdate = function () { };
var s, o, c = this, l = t.timepicker, u = t("html");
var n = this[0].value;
bstptid = $(this[0]);
e.test(n) ? (n = n.split(":"), s = +n[0], o = +n[1]) : (n = new Date, s = n.getHours(), o = n.getMinutes());
$(l.title).html(l.headerText);
$(l.mobileTitle).html(l.headerText);
$(l.applyBtn).html(l.applyText);
l.inputTarget = c, l.content.insertAfter(this[0].parentElement),
l.hour = s, l.minute = o, l.choseAll.show(), l.choseHour.hide(), l.choseMinute.hide(), l.update(), t.timepicker.bindEvent();
}, t.fn.closeTimepicker = function (i) {
var c = this, l = t.timepicker;
l.content.off().remove(), l.hasBind = !1;
}, t
});