' +
'
' + $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 && (scope.time == null || scope.time == undefined)) {
scope.time = new Date();
scope.time.setHours(12, 0, 0, 0);
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': '=',
'tooltipmaxpeople': '@',
'editable': '=',
},
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');
});
})
}
if (scope.editable == true) {
scope.maxpeople = 99;
}
},
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) { //Check changes on people + and - buttons
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.inputChange = function (inputadult, inputundertwelve, inputunderfive) { //Check changes on people inputs
if (inputadult === undefined) inputadult = 0; if (inputundertwelve === undefined) inputundertwelve = 0; if (inputunderfive === undefined) inputunderfive = 0;
if (inputadult != null) { //Adult input
$scope.people = $scope.childrenundertwelve + $scope.childrenunderfive;
if (inputadult < 0) $scope.adults = 0;
else if (inputadult > $scope.maxpeople - $scope.people) $scope.adults = ($scope.maxpeople - $scope.people);
else $scope.adults = inputadult;
}
if (inputundertwelve != null) { //Under twelve input
$scope.people = $scope.adults + $scope.childrenunderfive;
if (inputundertwelve < 0) $scope.childrenundertwelve = 0;
else if (inputundertwelve > $scope.maxpeople - $scope.people) $scope.childrenundertwelve = ($scope.maxpeople - $scope.people);
else $scope.childrenundertwelve = inputundertwelve;
}
if (inputunderfive != null) { //Under five input
$scope.people = $scope.adults + $scope.childrenundertwelve;
if (inputunderfive < 0) $scope.childrenunderfive = 0;
else if (inputunderfive > $scope.maxpeople - $scope.people) $scope.childrenunderfive = ($scope.maxpeople - $scope.people);
else $scope.childrenunderfive = inputunderfive;
}
$scope.people = $scope.adults + $scope.childrenundertwelve + $scope.childrenunderfive;
}
$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("");
}
scope.$parent.clearQuickFilter(); //Reset activitie screen
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': '@',
'iconType': '=',
},
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 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.uservalue != null) { //format 00:00 -> convert to datehour
$scope.internalModelDic[modelField].uservalue = formatDateFromHourString(field.uservalue);
}
fieldContainer.append(newFieldElem);
//Add watchers (convert data format)
addTimeWatchers(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 readOnly = false;
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 addTimeWatchers(modelField, fieldName) {
$scope.$watch(modelField + '.uservalue', function (newValue, oldValue) {
if (newValue !== oldValue) {
if (newValue !== undefined && newValue !== null) {
$scope.internalModelDic[modelField].uservalue = formatDateFromHourString(newValue); //format 00:00 to date
}
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) {
if (newValDate !== undefined && newValDate !== null) {
//format date to 00:00
modelScope.uservalue = formatHourFromDate(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);
}
}
};
/////////////////////////
//Hour format
function formatHourFromDate(date) {
if (date != undefined && date != null) {
var hours = date.getHours().toString().padStart(2, '0');
var minutes = date.getMinutes().toString().padStart(2, '0');
return `${hours}:${minutes}`;
}
return null;
}
function formatDateFromHourString(timeStr) {
if (timeStr != undefined && timeStr != null) {
var today = new Date();
// Dividir la hora en horas y minutos
var timeParts = timeStr.split(':');
var hours = parseInt(timeParts[0], 10);
var minutes = parseInt(timeParts[1], 10);
var date = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate(),
hours,
minutes
);
return date;
}
return null;
}
//////////////////////////////////////////////////
//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);
}
};
},
};
});
})();
/*
AngularJS v1.4.5
(c) 2010-2015 Google, Inc. http://angularjs.org
License: MIT
*/
(function(p,g,l){'use strict';function m(b,a,f){var c=f.baseHref(),k=b[0];return function(b,d,e){var f,h;e=e||{};h=e.expires;f=g.isDefined(e.path)?e.path:c;d===l&&(h="Thu, 01 Jan 1970 00:00:00 GMT",d="");g.isString(h)&&(h=new Date(h));d=encodeURIComponent(b)+"="+encodeURIComponent(d);d=d+(f?";path="+f:"")+(e.domain?";domain="+e.domain:"");d+=h?";expires="+h.toUTCString():"";d+=e.secure?";secure":"";e=d.length+1;4096
4096 bytes)!");k.cookie=d}}g.module("ngCookies",["ng"]).provider("$cookies",[function(){var b=this.defaults={};this.$get=["$$cookieReader","$$cookieWriter",function(a,f){return{get:function(c){return a()[c]},getObject:function(c){return(c=this.get(c))?g.fromJson(c):c},getAll:function(){return a()},put:function(c,a,n){f(c,a,n?g.extend({},b,n):b)},putObject:function(c,b,a){this.put(c,g.toJson(b),a)},remove:function(a,k){f(a,l,k?g.extend({},b,k):b)}}}]}]);g.module("ngCookies").factory("$cookieStore",
["$cookies",function(b){return{get:function(a){return b.getObject(a)},put:function(a,f){b.putObject(a,f)},remove:function(a){b.remove(a)}}}]);m.$inject=["$document","$log","$browser"];g.module("ngCookies").provider("$$cookieWriter",function(){this.$get=m})})(window,window.angular);
//# sourceMappingURL=angular-cookies.min.js.map
/**!
* 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;
}]);
/*
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&&0d/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 ngClientDashboardService = angular.module('ngClientDashboardService', ['ngResource']);
ngClientDashboardService.service('ClientDashboard', ['$resource', '$http', function ($resource, $http) {
this.getPagedOrderDetailsByClient = function (page, token, prefix) {
return $http.post(prefix + '/client-order-list-get-data-ag', {
page: page,
}
, {
headers: {
'__RequestVerificationToken': token
}
});
};
/*Creación de ordenes para terceros.*/
this.getPagedOrdersList = function (page, prefix, antiForgeryToken, dateFilterOpt, from, to, searchEmail, searchOrderCode, searchTransactionId, searchStatus, searchCity, searchCounty, searchService, isSearch) {
return $http.post(prefix + '/agent-third-order-switchpage-ag', {
page: page,
dateFilterOpt: dateFilterOpt,
from: from,
to: to,
searchEmail: searchEmail,
orderCode: searchOrderCode,
transId: searchTransactionId,
status: searchStatus,
idCity: searchCity,
countryCode: searchCounty,
serviceCode: searchService,
isSearch: isSearch
}
, {
headers: {
'__RequestVerificationToken': antiForgeryToken
}
});
};
this.getOrderIndex = function ( prefix, antiForgeryToken, email) {
return $http.post(prefix + '/agent-third-order-indexfiltered-ag', {
email:email,
}
, {
headers: {
'__RequestVerificationToken': antiForgeryToken
}
});
};
this.getClientDataByEmail = function (email) {
var token = $('input[name="__RequestVerificationToken"]').val();
return $http.post('/agent-get-client-data-ag', {
email: email
}
, {
headers: {
'__RequestVerificationToken': token
}
});
};
this.getPagedOrderApprovmentPending = function (page, prefix, antiForgeryToken, searchEmail, searchOrderCode, searchCity, searchCountry, searchService) {
return $http.post(prefix + '/agent-order-pending-approvement-list-ag', {
page: page,
searchEmail: searchEmail,
orderCode: searchOrderCode,
idCity: searchCity,
countryCode: searchCountry,
serviceCode: searchService
}
, {
headers: {
'__RequestVerificationToken': antiForgeryToken
}
});
};
this.getRecentBookings = function (filter, prefix) {
return $resource(prefix + 'api/clientdashboard/getrecentbooking/:flt', { flt: filter },
{
query: { method: 'GET', params: {}, isArray: true }
}).query().$promise;
};
}]);
function transformGetToInt(json, headerGetter) {
var fromJson = angular.fromJson({ raw: json });
return fromJson;
}
})();
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.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.isTicket = $scope.Model.onlyTickets;
$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'];
/**
* Checklist-model
* AngularJS directive for list of checkboxes
*/
angular.module('checklist-model', [])
.directive('checklistModel', ['$parse', '$compile', function($parse, $compile) {
// contains
function contains(arr, item, comparator) {
if (angular.isArray(arr)) {
for (var i = arr.length; i--;) {
if (comparator(arr[i], item)) {
return true;
}
}
}
return false;
}
// add
function add(arr, item, comparator) {
arr = angular.isArray(arr) ? arr : [];
if(!contains(arr, item, comparator)) {
arr.push(item);
}
return arr;
}
// remove
function remove(arr, item, comparator) {
if (angular.isArray(arr)) {
for (var i = arr.length; i--;) {
if (comparator(arr[i], item)) {
arr.splice(i, 1);
break;
}
}
}
return arr;
}
// http://stackoverflow.com/a/19228302/1458162
function postLinkFn(scope, elem, attrs) {
// compile with `ng-model` pointing to `checked`
$compile(elem)(scope);
// getter / setter for original model
var getter = $parse(attrs.checklistModel);
var setter = getter.assign;
var checklistChange = $parse(attrs.checklistChange);
// value added to list
var value = $parse(attrs.checklistValue)(scope.$parent);
var comparator = angular.equals;
if (attrs.hasOwnProperty('checklistComparator')){
comparator = $parse(attrs.checklistComparator)(scope.$parent);
}
// watch UI checked change
scope.$watch('checked', function(newValue, oldValue) {
if (newValue === oldValue) {
return;
}
var current = getter(scope.$parent);
if (newValue === true) {
setter(scope.$parent, add(current, value, comparator));
} else {
setter(scope.$parent, remove(current, value, comparator));
}
if (checklistChange) {
checklistChange(scope);
}
});
// declare one function to be used for both $watch functions
function setChecked(newArr, oldArr) {
scope.checked = contains(newArr, value, comparator);
}
// watch original model change
// use the faster $watchCollection method if it's available
if (angular.isFunction(scope.$parent.$watchCollection)) {
scope.$parent.$watchCollection(attrs.checklistModel, setChecked);
} else {
scope.$parent.$watch(attrs.checklistModel, setChecked, true);
}
}
return {
restrict: 'A',
priority: 1000,
terminal: true,
scope: true,
compile: function(tElement, tAttrs) {
if (tElement[0].tagName !== 'INPUT' || tAttrs.type !== 'checkbox') {
throw 'checklist-model should be applied to `input[type="checkbox"]`.';
}
if (!tAttrs.checklistValue) {
throw 'You should provide `checklist-value`.';
}
// exclude recursion
tElement.removeAttr('checklist-model');
// local scope var storing individual checkbox model
tElement.attr('ng-model', 'checked');
return postLinkFn;
}
};
}]);
(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, latitude, longitude) {
return $resource(prefix + '/webapi/v2/userpurchase/addressesprediction', {},
{
query: {
method: 'POST',
params: { filter: filter, placeId: placeId, session: session, latitude: latitude, longitude: longitude },
isArray: true
}
}).query().$promise;
};
this.getAddressesPickup = function (filter, prefix) {
return $resource(prefix + '/webapi/v2/purchases/addressespickup', {},
{
query: {
method: 'POST',
params: {
filter: filter
},
isArray: true
}
}).query().$promise;
};
//Point resolution
this.resolvePlace = function (placeId, prefix, session) {
return $resource(prefix + '/webapi/v2/userpurchase/getplaceinfo?placeId=:placeId&sessionToken=:session', { placeId: placeId, session: session },
{
query: { method: 'GET', params: {}, isArray: false }
}).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;
}
})();
var AgentEditDetailsController = function ($scope, $http, $location, $state, $timeout, $window, shApi, CanonicalUrl, Translator, AntiForgery) {
$scope.initialize = function (clientData,isClient) {
$scope.Model = {};
$scope.Model.error = false;
$scope.Model.culture = Translator.getCurrentCulture();
$scope.Model.clientData = {};
$scope.Model.clientEditData = {};
$scope.Model.handled = false;
$scope.Model.showClientData = true;
$scope.Model.pageError = null;
$scope.Model.showAlerts = {};
$scope.Model.clientConfirmPassword = null;
$scope.Model.clientData = arguments[0];
$scope.Model.isClient = JSON.parse(isClient.toLowerCase());
$scope.Model.showModalPassword = false;
//MODALS
shApi.navigationStateControl($scope.Model);
//FORM ERROR
shApi.defineRequired($scope, $scope.Model);
shApi.interceptor40x($scope, $scope.Model);
shApi.interceptor25x($scope, $scope.Model);
AntiForgery.getAntiForgery($scope.Model.prefix).then(function (tok) {
$scope.Model.Token = tok;
$scope.showChangeFullname();
});
}
$scope.saveClientData = function (e) {
$scope.Model.pageError = null;
if (shApi.preventNavigate(e, $scope.Model)) return;
if ($scope.Model.formUpdateClientData.$valid) {
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-dashboard-client-data-update-ag'), {
userName: $scope.Model.clientEditData.name,
userSurname: $scope.Model.clientEditData.surname,
userLastname: (typeof $scope.Model.clientEditData.lastname == 'undefined' ? null : $scope.Model.clientEditData.lastname),
phoneNumber: $scope.Model.clientEditData.mainPhone,
phoneCode: $scope.Model.clientEditData.mainPhoneCode
}, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
if (status == 251) {
$scope.Model.showChangeFullname = false;
$scope.Model.showChangePhone = false;
$scope.Model.clientData = $scope.Model.clientEditData;
$scope.Model.clientData.fullName = $scope.Model.clientData.name + ' ' + $scope.Model.clientData.surname;
if ($scope.Model.clientData.lastname != null && $scope.Model.clientData.lastname != undefined)
$scope.Model.clientData.fullName = $scope.Model.clientData.fullName + ' ' + $scope.Model.clientData.lastname;
if ($scope.Model.clientEditData.mainPhoneCode != undefined && $scope.Model.clientEditData.mainPhone != undefined) {
$scope.Model.clientData.mainPhone = $scope.Model.clientEditData.mainPhone;
}
}
})
.error(function (data, status, headers, config) {
shApi.handleError($scope.Model,data);
});
}
}
$scope.showChangeFullname = function (e) {
$scope.Model.showChangeFullname = !$scope.Model.showChangeFullname;
if ($scope.Model.showChangeFullname === true)
$scope.copyEditData();
else {
$scope.Model.clientEditData.fullName = null;
$scope.cancelEditData(e);
}
}
$scope.showChangePhone = function (e) {
$scope.Model.showChangePhone = !$scope.Model.showChangePhone;
if ($scope.Model.showChangePhone === true)
$scope.copyEditData();
else {
$scope.Model.clientEditData.mainPhone = null;
$scope.cancelEditData(e);
}
}
$scope.copyEditData = function()
{
$scope.Model.clientEditData = angular.copy($scope.Model.clientData);
if ($scope.Model.clientEditData.mainPhone != 'undefined' && $scope.Model.clientEditData.mainPhone != null) {
var phone = $scope.Model.clientEditData.mainPhone;
if (phone.split('-').length == 2) {
$scope.Model.clientEditData.mainPhoneCode = phone.split('-')[0];
$scope.Model.clientEditData.mainPhone = phone.split('-')[1];
}
}
else if ($scope.Model.clientCountry != null && typeof $scope.Model.clientCountry.Dialcode != 'undefined') {
$scope.Model.clientEditData.mainPhoneCode = $scope.Model.clientCountry.Dialcode;
}
}
$scope.cancelEditData = function (e) {
$scope.Model.formUpdateClientData.$setUntouched();
$scope.Model.formUpdateClientData.$setPristine();
}
$scope.getFileLink = function (link) {
if (typeof link != 'undefined' && link != null)
return "/download-file-link/?filelink=" + link;
}
$scope.clearResetClientPasswordForm = function (e) {
if (shApi.preventNavigate(e)) return;
$scope.Model.clientPassword = null;
$scope.Model.clientConfirmPassword = null;
$scope.Model.formUpdateClientPassword.$setUntouched();
$scope.Model.formUpdateClientPassword.$setPristine();
$scope.Model.showModalPassword = false;
}
$scope.$watch('Model.clientConfirmPassword', function (newValue, oldValue) {
if (newValue !== oldValue) {
$scope.comparePassword();
;
}
});
$scope.$watch('Model.clientPassword', function (newValue, oldValue) {
if (newValue !== oldValue) {
$scope.comparePassword();
}
});
$scope.comparePassword = function (e) {
if ($scope.Model.clientPassword != null && $scope.Model.clientPassword != undefined && $scope.Model.clientPassword != "" && $scope.Model.clientConfirmPassword != null && $scope.Model.clientConfirmPassword != undefined && $scope.Model.clientConfirmPassword != "" && $scope.Model.clientConfirmPassword != $scope.Model.clientPassword) {
$scope.Model.formUpdateClientPassword.clientConfirmPassword.$setValidity('errorCompare', false);
} else {
$scope.Model.formUpdateClientPassword.clientConfirmPassword.$setValidity('errorCompare', true);
}
}
$scope.saveClientPassword = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
if ($scope.Model.formUpdateClientPassword.$valid && $scope.Model.clientConfirmPassword != undefined && $scope.Model.clientConfirmPassword != null) {
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-update-password-ag'), {
password: (typeof $scope.Model.clientPassword == 'undefined' ? null : $scope.Model.clientPassword)
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
if (status == 251) {
$scope.Model.resetEmployeePassword = false;
$scope.Model.partnerPassword = null;
$scope.Model.partnerConfirmPassword = null;
$scope.Model.showPartnerData = true;
$('#modalChangePwd').modal('hide');
}
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
$scope.Model.error = true;
});
}
else {
$scope.Model.continue = true;
}
}
//Change pwd in modal window
$('#modalChangePwd').on('hidden.bs.modal', function () {
$scope.Model.clientPassword = null;
$scope.Model.clientConfirmPassword = null;
$scope.Model.formUpdateClientPassword.$setUntouched();
$scope.Model.formUpdateClientPassword.$setPristine();
})
}
AgentEditDetailsController.$inject = ['$scope', '$http', '$location', '$state', '$timeout', '$window', 'shApi', 'CanonicalUrl', 'Translator', 'AntiForgery'];
var AgentLoginController = function ($scope, $http, $location, $state, $timeout, shApi, $window, CanonicalUrl, Translator, AntiForgery) {
$scope.initialize = function () {
$scope.Model = {};
$scope.Model.showAlerts = {};
$scope.Model.working = false;
$scope.Model.continue = false;
$scope.Model.handled = false;
//MODALS
shApi.navigationStateControl($scope.Model);
//FORM ERROR
shApi.defineRequired($scope, $scope.Model);
shApi.interceptor25x($scope, $scope.Model);
shApi.interceptor23x($scope, $scope.Model);
shApi.interceptor55x($scope, $scope.Model);
AntiForgery.getAntiForgery($scope.Model.prefix).then(function (tok) {
$scope.Model.Token = tok;
});
$scope.Model.culture = Translator.getCurrentCulture();
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
$state.go("agent-account-login", { pre: CanonicalUrl.getFolderPrefix($scope.Model.culture), targeturl: CanonicalUrl.getCanonicalUrl($scope.Model.culture, 'agent-account-login') });
$scope.Model.remember = true;
};
$scope.ConfirmAgentLogin = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
if ($scope.Model.agentLogin.$valid && $scope.Model.password != null) {
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-account-login-ag'), {
email: $scope.Model.email,
password: $scope.Model.password,
remember: $scope.Model.remember
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
if (status == 254) {
$scope.Model.navigating = true;
if ($scope.Model.returnUrl != "") {
document.location.href = $scope.Model.returnUrl;
}
else {
document.location.href = CanonicalUrl.getUrl($scope.Model.culture, data.data);
}
} else {
$scope.Model.incorrectData = true;
$scope.Model.errorLoginMsg = data;
}
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
$scope.Model.error = true;
});
} else if (!$scope.Model.handled) {
$scope.Model.continue = true;
window.setTimeout(function () { shApi.scrollToError($scope.Model.topIntegrationOffset); }, 350);
}
};
}
AgentLoginController.$inject = ['$scope', '$http', '$location', '$state', '$timeout', 'shApi', '$window', 'CanonicalUrl', 'Translator', 'AntiForgery'];
var ClientDashBoardController = function ($scope, $http, $location, $state, $timeout, $window, shApi, CanonicalUrl, Translator, ClientDashboard, Charts, AntiForgery) {
var from = null;
var to = null;
var wordFilter = null;
$scope.initialize = function () {
$scope.Model = {};
$scope.Model.error = false;
$scope.Model.count = -1;
$scope.Model.totalPages = 0;
$scope.Model.working = false;
$scope.Model.culture = Translator.getCurrentCulture();
$scope.Model.handled = false;
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
$scope.Model.wordFilter = null;
$scope.Model.pageError = null;
$scope.Model.showAlerts = {};
$scope.Model.clientConfirmPassword = null;
//MODALS
shApi.navigationStateControl($scope.Model);
//FORM ERROR
shApi.defineRequired($scope, $scope.Model);
shApi.interceptor40x($scope, $scope.Model);
shApi.interceptor25x($scope, $scope.Model);
$scope.Model.from = shApi.serverUTCDateFromTime(new Date().getTime());
$scope.Model.to = shApi.serverUTCDateFromTime(new Date().getTime());
AntiForgery.getAntiForgery($scope.Model.prefix).then(function (tok) {
$scope.Model.Token = tok;
});
}
$scope.getFileLink = function (link) {
if (typeof link != 'undefined' && link != null)
return "/download-file-link/?filelink=" + link;
}
$scope.getPendingOrdersResume = function (model) {
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'partner-get-paymentpending-orders-resume-ag'), {
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
}).success(function (data, status, headers, config) {
$scope.Model.pendingOrdersResume = data;
}).error(function (data, status, headers, config) {
shApi.handleError(model, data);
});
};
$scope.clearResetClientPasswordForm = function (e) {
if (shApi.preventNavigate(e)) return;
$scope.Model.clientPassword = null;
$scope.Model.clientConfirmPassword = null;
$scope.Model.formUpdateClientPassword.$setUntouched();
$scope.Model.formUpdateClientPassword.$setPristine();
$('#modalChangePwd').modal('hide');
}
$scope.saveClientPassword = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
if ($scope.Model.formUpdateClientPassword.$valid && $scope.Model.clientConfirmPassword != undefined && $scope.Model.clientConfirmPassword != null) {
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-update-password-ag'), {
password: (typeof $scope.Model.clientPassword == 'undefined' ? null : $scope.Model.clientPassword)
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
if (status == 251) {
$scope.Model.resetEmployeePassword = false;
$scope.Model.partnerPassword = null;
$scope.Model.partnerConfirmPassword = null;
$scope.Model.showPartnerData = true;
$('#modalChangePwd').modal('hide');
}
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
$scope.Model.error = true;
});
}
else {
$scope.Model.continue = true;
}
}
//Change pwd in modal window
$('#modalChangePwd').on('hidden.bs.modal', function () {
$scope.Model.clientPassword = null;
$scope.Model.clientConfirmPassword = null;
$scope.Model.formUpdateClientPassword.$setUntouched();
$scope.Model.formUpdateClientPassword.$setPristine();
})
}
ClientDashBoardController.$inject = ['$scope', '$http', '$location', '$state', '$timeout', '$window', 'shApi', 'CanonicalUrl', 'Translator', 'ClientDashboard', 'Charts', 'AntiForgery'];
var ClientDashboardKPIController = function ($scope, $http, $location, $state, $timeout, $window, shApi, CanonicalUrl, Translator, Charts, AntiForgery) {
$scope.initialize = function (email, from, to) {
$scope.Model = {};
$scope.Model.culture = Translator.getCurrentCulture();
$scope.Model.continue = false;
shApi.interceptor25x($scope, $scope.Model);
shApi.interceptor40x($scope, $scope.Model);
//MODALS
shApi.navigationStateControl($scope.Model);
//FORM ERROR
shApi.defineRequired($scope, $scope.Model);
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
$scope.Model.TravelAgentEmail = email;
$scope.Model.from = from;
$scope.Model.to = to;
$scope.Model.usageResolution = "day";
$scope.Model.working = true;
AntiForgery.getAntiForgery($scope.Model.prefix).then(function (tok) {
$scope.Model.Token = tok;
setupCharts();
});
}
////GRAFICAS****************************************
function setupCharts() {
// 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($scope.printChart);
}
$scope.printChart = function () {
var resolution = '';
if ((new Date($scope.Model.to) - new Date($scope.Model.from)) / (1000 * 60 * 60 * 24) > 32)
resolution = 'month';
else
resolution = 'day';
// var data = getData(resolution, $scope.Model.from, $scope.Model.to, $scope.Model.TravelAgentEmail);
var data = {};
data.resolution = resolution;
data.from = $scope.Model.from;
data.to = $scope.Model.to;
data.email = $scope.Model.TravelAgentEmail;
// var dataChart = Charts.getClientChartData('client-sellsump-chart', data);
getDataForSellChart(resolution, $scope.Model.from, $scope.Model.to);
getDataForCountryChart(resolution, $scope.Model.from, $scope.Model.to);
getDataForTracCodeConversion(resolution, $scope.Model.from, $scope.Model.to);
}
function getDataForSellChart(resolution, from, to) {
if (from == undefined || to == undefined)
return;
var data = {};
data.resolution = resolution;
data.from = from;
data.to = to;
data.travelAgentEmail = $scope.Model.TravelAgentEmail;
Charts.getClientChartData("client-sellsump-chart", data, $scope.Model.prefix)
.then(function (response) {
var jsonResponse = JSON.parse(response.Data);
Charts.drawLineSimpleChart(jsonResponse.labels, jsonResponse.data, 'chart_div');
});
}
function getDataForCountryChart(resolution, from, to) {
if (from == undefined || to == undefined)
return;
var data = {};
data.resolution = resolution;
data.from = from;
data.to = to;
data.travelAgentEmail = $scope.Model.TravelAgentEmail;
Charts.getClientChartData("client-country-chart", data, $scope.Model.prefix)
.then(function (response) {
var jsonResponse = JSON.parse(response.Data);
Charts.drawPieChart(jsonResponse,'chart_trackConversion_div');
});
}
function getDataForTracCodeConversion(resolution, from, to) {
if (from == undefined || to == undefined)
return;
var data = {};
data.resolution = resolution;
data.from = from;
data.to = to;
data.travelAgentEmail = $scope.Model.TravelAgentEmail;
Charts.getClientChartData("client-sellsump-accumulated-chart", data, $scope.Model.prefix)
.then(function (response) {
var jsonResponse = JSON.parse(response.Data);
Charts.drawLineDoubleChart(jsonResponse.labels, jsonResponse.data, 'chart_trackSummary_div');
$scope.Model.working = false;
});
}
function transpose(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;
};
}
ClientDashboardKPIController.$inject = ['$scope', '$http', '$location', '$state', '$timeout', '$window', 'shApi', 'CanonicalUrl', 'Translator', 'Charts', 'AntiForgery'];
var ClientDashboardOrderDetailController = function ($scope, $http, $state, shApi, CanonicalUrl, Translator, ClientDashboard, AntiForgery) {
$scope.initialize = function (orderData, actionsAllowed) {
$scope.Model = {};
$scope.Model.culture = Translator.getCurrentCulture();
$scope.Model.orderData = orderData;
$scope.Model.showAlerts = {};
$scope.Model.actionsAllowed = actionsAllowed;
$scope.Model.continue = false;
AntiForgery.getAntiForgery($scope.Model.prefix).then(function (tok) {
$scope.Model.Token = tok;
});
shApi.interceptor25x($scope, $scope.Model);
shApi.interceptor40x($scope, $scope.Model);
//MODALS
shApi.navigationStateControl($scope.Model);
//FORM ERROR
shApi.defineRequired($scope, $scope.Model);
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
}
//Cancellation modal
$scope.openCancelationModal = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
$scope.Model.orderToCancel = {};
$scope.Model.orderToCancel.OrderCode = $scope.Model.orderData.orderCode;
$scope.Model.showCancelOrderModal = true;
$scope.Model.cancelationCode = null;
}
$scope.closeCancelationModal = function () {
$scope.Model.orderToCancel = {};
$scope.Model.showCancelOrderModal = false;
$scope.Model.cancelationCode = null;
};
$scope.requestCancellation = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
$scope.closeCancelationModal();
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'client-dashboard-request-cancellation-ag'), {
orderCode: $scope.Model.orderData.orderCode,
cancelationCode: $scope.Model.cancelationCode
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
location.reload();
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
});
}
//Voucher modal
$scope.openVoucherModal = function (e, order) {
if (e != undefined) { if (shApi.preventNavigate(e, $scope.Model)) return; };
$scope.Model.voucherOK = false;
$scope.Model.loadingVoucher = true;
$scope.Model.showVoucherOrderModal = true;
$scope.Model.voucherData = null;
$scope.downloadVoucher(e);
}
$scope.downloadVoucher = function (e) {
if (e != undefined) { if (shApi.preventNavigate(e, $scope.Model)) return; };
if ($scope.Model.voucherData == null) {
$scope.Model.loadingVoucher = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'client-get-voucher-ag'), {
token: $scope.Model.orderData.voucherToken
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
if (status == 253 || data == null) {
$scope.Model.voucherError = true;
}
else {
$scope.Model.voucherData = data;
$scope.Model.voucherOK = true;
shApi.getPdfFile($scope.Model.voucherData, $scope.Model.orderData.orderCode);
}
$scope.Model.loadingVoucher = false;
})
.error(function (data, status, headers, config) {
$scope.Model.loadingVoucher = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
});
}
else {
shApi.getPdfFile($scope.Model.voucherData, $scope.Model.orderData.OrderCode);
$scope.Model.voucherOK = true;
$scope.Model.loadingVoucher = false;
}
}
$scope.closeVoucherModal = function (e) {
if (e != undefined) { if (shApi.preventNavigate(e, $scope.Model)) return; };
$scope.Model.showVoucherOrderModal = false;
$scope.Model.voucherOK = false;
$scope.Model.loadingVoucher = false;
$scope.Model.voucherError = false;
$scope.Model.voucherData = null;
}
//////
}
ClientDashboardOrderDetailController.$inject = ['$scope', '$http', '$state', 'shApi', 'CanonicalUrl', 'Translator', 'ClientDashboard', 'AntiForgery'];
var ClientDashboardSalesViewerController = function ($scope, $http, $location, $state, $timeout, $window, shApi, CanonicalUrl, Translator, Charts, Lookups, AntiForgery) {
$scope.initialize = function (servicesFilter, dataStr, pricesStr, referenceStr, nameStr, agentStr, statusStr, paidDateStr, createdStr, marginStr, paidStr, currencyStr, providerStr, hideCommissions) {
$scope.Model = {};
$scope.Model.filters = {};
$scope.Model.culture = Translator.getCurrentCulture();
$scope.Model.strings = {};
$scope.Model.strings.data = dataStr;
$scope.Model.strings.prices = pricesStr;
$scope.Model.strings.reference = referenceStr;
$scope.Model.strings.name = nameStr;
$scope.Model.strings.agent = agentStr;
$scope.Model.strings.margin = marginStr;
$scope.Model.strings.status = statusStr;
$scope.Model.strings.paidDate = paidDateStr;
$scope.Model.strings.created = createdStr;
$scope.Model.strings.paid = paidStr;
$scope.Model.strings.currency = currencyStr;
$scope.Model.strings.providers = providerStr;
$scope.Model.hideCommissions = hideCommissions;
$scope.Model.showFiltersModal = false;
$scope.Model.page = 0;
$scope.Model.totalPages = 0;
$scope.Model.perPage = 10;
$scope.Model.continue = false;
var now = new Date();
var previousWeek = new Date(now);
previousWeek.setDate(previousWeek.getDate() - 7);
$scope.Model.filters.to = now.toDateString();
$scope.Model.filters.from = previousWeek.toDateString();
$scope.Model.servicesFilters = servicesFilter;
initializeTabulator();
shApi.interceptor25x($scope, $scope.Model);
shApi.interceptor40x($scope, $scope.Model);
//MODALS
shApi.navigationStateControl($scope.Model);
//FORM ERROR
shApi.defineRequired($scope, $scope.Model);
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
AntiForgery.getAntiForgery($scope.Model.prefix).then(function (tok) {
$scope.Model.Token = tok;
$scope.getData(null, false);
});
}
$scope.switchpage = function (type) {
switch (type) {
case 0:
$scope.Model.page--;
$("#tabulator").tabulator("setPage", $scope.Model.page+1);
break;
case 1:
$scope.Model.page++;
$("#tabulator").tabulator("setPage", $scope.Model.page+1);
break;
case 2:
$scope.Model.page = $("#tabulator").tabulator("getPageMax")-1;
$("#tabulator").tabulator("setPage", $scope.Model.page+1);
break;
case 3:
$scope.Model.page = 0;
$("#tabulator").tabulator("setPage", $scope.Model.page+1);
break;
}
}
$scope.getData = function (e, forExcel) {
if (e != undefined && e != null && shApi.preventNavigate(e, $scope.Model)) return;
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-sales-viewer-get-data-ag'), {
from: $scope.Model.filters.from,
to: $scope.Model.filters.to,
forExcel: forExcel
}
,{
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data) {
angular.forEach(data.bookings, function (value, key) {
value.Created = new Date(value.Created);
if (value.Paid != null)
value.Paid = new Date(value.Paid);
});
angular.forEach(data.services, function (value, key) {
value.Date = new Date(value.Date);
});
$scope.Model.bookings = data.bookings;
$scope.Model.services = data.services;
if ($scope.Model.bookings.length % $scope.Model.perPage == 0) {
$scope.Model.totalPages = Math.trunc($scope.Model.bookings.length / $scope.Model.perPage);
}
else {
$scope.Model.totalPages = Math.trunc($scope.Model.bookings.length / $scope.Model.perPage) + 1;
}
$scope.Model.page = 0;
$("#tabulator").tabulator("setData", $scope.Model.bookings);
$scope.Model.working = false;
if (forExcel == true) {
$scope.createExcel();
}
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
});
}
$scope.getCities = function (filter) {
return Lookups.getAllCities(filter, $scope.Model.prefix)
.then(function (response) {
return response;
});
};
function initializeTabulator() {
$("#tabulator").tabulator({
layout: "fitColumns",
pagination: "local",
paginationSize: $scope.Model.perPage,
responsiveLayout: "collapse",
responsiveLayoutCollapseStartOpen: false,
columns:
[//Define Table Columns
{
title: $scope.Model.strings.data,
columns: [
{
title: "OrderCode",
field: "OrderCode",
},
{
title: $scope.Model.strings.reference,
field: "Reference",
},
{
title: $scope.Model.strings.status,
field: "OrderStatus",
},
{
title: $scope.Model.strings.created,
field: "Created",
},
{
title: $scope.Model.strings.providers,
field: "Providers",
}
]
},
{
title: $scope.Model.strings.agent,
columns: [
{
title: $scope.Model.strings.name,
field: "AgentName",
},
{
title: "Email",
field: "AgentEmail",
}
]
},
{
title: $scope.Model.strings.prices,
columns: [
{
title: $scope.Model.strings.paid,
field: "TotalPaid",
},
{
title: $scope.Model.strings.currency,
field: "CurrencyCode",
},
]
},
],
});
}
$scope.createExcel = function () {
var wb = XLSX.utils.book_new();
angular.forEach($scope.Model.bookings, function (value, key) {
delete value.Paid;
delete value.TotalPaid;
delete value.Net;
delete value.BaseST;
delete value.MarginPartner;
if ($scope.Model.hideCommissions) {
delete value.PvRetailer;
}
});
angular.forEach($scope.Model.services, function (value, key) {
delete value.BaseST;
delete value.TotalPaid;
delete value.Net;
delete value.MarginPartner;
if ($scope.Model.hideCommissions) {
delete value.MarginST;
}
});
var bookingsXslx = XLSX.utils.json_to_sheet($scope.Model.bookings);
var servicesXslx = XLSX.utils.json_to_sheet($scope.Model.services);
XLSX.utils.book_append_sheet(wb, bookingsXslx, "Bookings");
XLSX.utils.book_append_sheet(wb, servicesXslx, "Services");
var wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });
var blob = new Blob([s2ab(wbout)], { type: "application/octet-stream" });
var from = $scope.Model.filters.from;
var to = $scope.Model.filters.to;
if (window.navigator.msSaveOrOpenBlob) // IE10+
window.navigator.msSaveOrOpenBlob(blob, "report" + from.getFullYear() + "-" + (from.getMonth() + 1) + "-" + from.getDate() + " to " + to.getFullYear() + "-" + (to.getMonth() + 1) + "-" + to.getDate() + ".xlsx");
else { // Others
var a = document.createElement("a"),
url = URL.createObjectURL(blob);
a.href = url;
a.download = "report" + from.getFullYear() + "-" + (from.getMonth() + 1) + "-" + from.getDate() + " to " + to.getFullYear() + "-" + (to.getMonth() + 1) + "-" + to.getDate() + ".xlsx";
document.body.appendChild(a);
a.click();
setTimeout(function () {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
}
}
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
$scope.clearFilters = function () {
var now = new Date();
$scope.Model.filters.to = now;
$scope.Model.filters.from = now;
$scope.Model.showFiltersModal = false;
$scope.getData($scope.Model, false);
}
}
ClientDashboardSalesViewerController.$inject = ['$scope', '$http', '$location', '$state', '$timeout', '$window', 'shApi', 'CanonicalUrl', 'Translator', 'Charts', 'Lookups', 'AntiForgery'];
var ClientLoginController = function ($scope, $http, $location, $state, $timeout, shApi, $window, CanonicalUrl, Translator, AntiForgery) {
$scope.initialize = function () {
$scope.Model = {}
$scope.Model.working = false;
$scope.Model.continue = false;
$scope.Model.handled = false;
//MODALS
shApi.navigationStateControl($scope.Model);
//FORM ERROR
shApi.defineRequired($scope, $scope.Model);
shApi.interceptor25x($scope, $scope.Model);
shApi.interceptor23x($scope, $scope.Model);
shApi.interceptor55x($scope, $scope.Model);
$scope.Model.culture = Translator.getCurrentCulture();
$state.go("client-account-login", { pre: CanonicalUrl.getFolderPrefix($scope.Model.culture), targeturl: CanonicalUrl.getCanonicalUrl($scope.Model.culture, 'client-account-login') });
AntiForgery.getAntiForgery($scope.Model.prefix).then(function (tok) {
$scope.Model.Token = tok;
});
$scope.Model.remember = true;
};
$scope.ConfirmClientLogin = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
if ($scope.Model.clientLogin.$valid && $scope.Model.password != null) {
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'client-account-login-ag'), {
email: $scope.Model.email,
password: $scope.Model.password,
remember: $scope.Model.remember
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token,
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
if (status == 254) {
$scope.Model.navigating = true;
if ($scope.Model.returnUrl != "") {
document.location.href = $scope.Model.returnUrl;
}
else {
document.location.href = CanonicalUrl.getUrl($scope.Model.culture, data.data);
}
} else {
$scope.Model.incorrectData = true;
$scope.Model.errorLoginMsg = data;
}
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
$scope.Model.error = true;
})
.then(function (response) {
AntiForgery.getAntiForgery($scope.Model.prefix).then(function (tok) {
$scope.Model.Token = tok;
});
}
);
} else if (!$scope.Model.handled) {
$scope.Model.continue = true;
window.setTimeout(function () { shApi.scrollToError($scope.Model.topIntegrationOffset); }, 350);
}
};
}
ClientLoginController.$inject = ['$scope', '$http', '$location', '$state', '$timeout', 'shApi', '$window', 'CanonicalUrl', 'Translator', 'AntiForgery'];
var ClientOrderApprovingListDashBoardController = function ($scope, $http, $location, $state, $timeout, ClientDashboard, CanonicalUrl, Translator, shApi, $window, Lookups, AntiForgery) {
$scope.initialize = function () {
$scope.Model = {};
$scope.Model.count = -1;
$scope.Model.totalPages = 0;
$scope.Model.working = false;
$scope.Model.culture = Translator.getCurrentCulture();
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
$scope.Model.wordFilter = null;
//MODALS
shApi.navigationStateControl($scope.Model);
//FORM ERROR
shApi.defineRequired($scope, $scope.Model);
shApi.interceptor25x($scope, $scope.Model);
shApi.interceptor40x($scope, $scope.Model);
shApi.interceptor55x($scope, $scope.Model);
shApi.timeout($scope);
$scope.Model.showAlerts = {};
$scope.Model.checked = 0;
AntiForgery.getAntiForgery($scope.Model.prefix).then(function (tok) {
$scope.Model.Token = tok;
$scope.switchpage(1);
});
}
$scope.switchpage = function (type) {
if (type == 1)
$scope.Model.count = $scope.Model.count + 1;
else if (type == 0)
$scope.Model.count = $scope.Model.count - 1;
else if (type == 2) {
$scope.Model.count = $scope.Model.totalPages - 1;
}
else if (type == 3) {
$scope.Model.count = 0;
}
$scope.getPagedOrderApprovmentPendingList();
}
$scope.getPagedOrderApprovmentPendingList = function () {
$scope.Model.working = true;
var city = $scope.Model.searchCity;
var idCity = 0;
if (city != undefined && city != null) {
if (city.IdCity != undefined && city.IdCity != null)
idCity = city.IdCity;
}
var countryCode = null;
if ($scope.Model.searchCountry != undefined && $scope.Model.searchCountry != null)
countryCode = $scope.Model.searchCountry.Code;
ClientDashboard.getPagedOrderApprovmentPending($scope.Model.count, $scope.Model.prefix, $scope.Model.Token, $scope.Model.email, $scope.Model.orderCode, idCity, countryCode, $scope.Model.searchService)
.success(function (data, status, headers, config) {
$scope.Model.orders = data.budgets;
$scope.Model.totalPages = data.pages;
$scope.Model.working = false;
$scope.Model.checked = 0;
})
.error(function (data, status, headers, config) {
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
$scope.Model.error = true;
$scope.Model.working = false;
});
}
//obtiene ciudades
$scope.getCities = function (filter) {
return Lookups.getAllCities(filter, $scope.Model.prefix)
.then(function (response) {
return response;
});
};
//obtiene los paises
$scope.getCountries = function (filter) {
return Lookups.getCountries(filter, $scope.Model.prefix)
.then(function (response) {
return response;
});
};
//Confirmar presupuesto
$scope.approveOrderDialog = function (e) {
if (shApi.preventNavigate(e, $scope.Model))
return;
$scope.Model.approvingOrder = true;
}
$scope.approveOrder = function (e) {
if (e == 1) {
$scope.Model.approvingOrder = false;
var orders = $scope.Model.orders.filter(isChecked);
var orderCodes = orders.map(getOrderCode);
if (orderCodes != null && orderCodes.length >= 1) {
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-approve-order-ag'), {
orderCodes: orderCodes
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
refresh();
$scope.Model.working = false;
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
});
} else {
$scope.Model.errorMsg = Translator.getTranslation('modal_error');
$scope.Model.error = true;
}
}
else {
$scope.Model.approvingOrder = false;
}
}
$scope.check = function (checked) {
checked ? $scope.Model.checked++ : $scope.Model.checked--;
}
function refresh() {
$scope.getPagedOrderApprovmentPendingList();
$scope.Model.checked = 0;
}
function isChecked(order) {
return order.checked;
}
function getOrderCode(item, index) {
return item.OrderCode;
}
$scope.printOrders = function () {
$window.print()
}
}
ClientOrderApprovingListDashBoardController.$inject = ['$scope', '$http', '$location', '$state', '$timeout', 'ClientDashboard', 'CanonicalUrl', 'Translator', 'shApi', '$window', 'Lookups', 'AntiForgery'];
var ClientOrderFilteredController = function ($scope, shApi, Translator, ClientDashboard, AntiForgery) {
$scope.initialize = function () {
$scope.Model = {};
$scope.Model.error = false;
$scope.Model.count = -1;
$scope.Model.totalPages = 0;
$scope.Model.working = false;
$scope.Model.culture = Translator.getCurrentCulture();
$scope.Model.handled = false;
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
$scope.Model.timezoneOffset = shApi.getTimezoneOffset();
$scope.Model.wordFilter = null;
$scope.Model.pageError = null;
$scope.Model.showAlerts = {};
$scope.Model.clientConfirmPassword = null;
//MODALS
shApi.navigationStateControl($scope.Model);
//FORM ERROR
shApi.defineRequired($scope, $scope.Model);
shApi.interceptor40x($scope, $scope.Model);
shApi.interceptor25x($scope, $scope.Model);
$scope.Model.from = shApi.serverUTCDateFromTime(new Date().getTime());
$scope.Model.to = shApi.serverUTCDateFromTime(new Date().getTime());
AntiForgery.getAntiForgery($scope.Model.prefix).then(function (tok) {
$scope.Model.Token = tok;
$scope.getOrdersLists();
});
}
$scope.getOrdersLists = function () {
ClientDashboard.getOrderIndex($scope.Model.prefix, $scope.Model.Token,
$scope.Model.email)
.then(function (response) {
$scope.Model.nextOrders = response.data[0];
$scope.Model.actualOrders = response.data[1];
$scope.Model.pendingOrders = response.data[2];
});
}
}
ClientOrderFilteredController.$inject = ['$scope', 'shApi', 'Translator', 'ClientDashboard', 'AntiForgery'];
var SellsSumupClientDashBoardController = function ($scope, $http, $location, $state, $timeout, $window, shApi, CanonicalUrl, Translator, Validations, ClientDashboard) {
$scope.initialize = function (email, from, to) {
$scope.Model = {};
$scope.Model.culture = Translator.getCurrentCulture();
$scope.Model.continue = false;
shApi.interceptor25x($scope, $scope.Model);
shApi.interceptor40x($scope, $scope.Model);
//MODALS
shApi.navigationStateControl($scope.Model);
//FORM ERROR
shApi.defineRequired($scope, $scope.Model);
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
$scope.Model.TravelAgentEmail = email;
$scope.Model.from = from;
$scope.Model.to = to;
$scope.Model.usageResolution = "days";
setupCharts();
}
$scope.printChart = function () {
getDataForUsageChart($scope.Model.usageResolution, $scope.Model.usageFrom, $scope.Model.usageTo);
}
function getDataForUsageChart(resolution, from, to) {
$scope.Model.working = true;
var token = $('input[name="__RequestVerificationToken"]').val();
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'partner-dashboard-usage-ag'), {
email: $scope.Model.partnerEmail,
resolution: resolution,
from: from,
to: to,
}
, {
headers: {
'__RequestVerificationToken': token
}
})
.success(function (resul, status, headers, config) {
$scope.Model.working = false;
$scope.Model.Charts.Usage.data.labels = resul.label;
$scope.Model.Charts.Usage.data.datasets = [];
AddSerie(resul.visits.name, resul.visits.values, $scope.Model.Charts.Usage.data.datasets);
AddSerie(resul.carts.name, resul.carts.values, $scope.Model.Charts.Usage.data.datasets);
AddSerie(resul.confirmed.name, resul.confirmed.values, $scope.Model.Charts.Usage.data.datasets);
AddSerie(resul.abandoned.name, resul.abandoned.values, $scope.Model.Charts.Usage.data.datasets);
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
$scope.Model.error = true;
});
}
////GRAFICAS****************************************
function setupCharts() {
// 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($scope.printChart);
}
$scope.printChart = function () {
updateDataGoogleCharts($scope.Model.from, $scope.Model.to);
}
function updateDataGoogleCharts(from, to) {
if (from == undefined
|| to == undefined)
return;
var token = $('input[name="__RequestVerificationToken"]').val();
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'partner-dashboard-sells-ag'), {
travelAgentEmail: $scope.Model.TravelAgentEmail,
resolution: $scope.Model.usageResolution,
from: from,
to: to,
}
, {
headers: {
'__RequestVerificationToken': token
}
})
.success(function (resul, status, headers, config) {
drawChart(resul.labels, resul.data);
})
.error(function (data, status, headers, config) {
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
$scope.Model.error = true;
});
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
function drawChart(labels, values) {
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 = 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 == 1)
series[i - 1] =
{
targetAxisIndex: 0
};
if (i > 1) {
series[i - 1] =
{
targetAxisIndex: 1
};
}
};
var options = {
chartArea: { 'top': 10, 'left': 60 , 'right' : 30 }, //, 'width': '90%', 'height': '65%' },
hAxis: {
slantedText: true,
slantedTextAngle: 30,
},
legend: { position: 'top' },
series: {
0: { targetAxisIndex: 0 },
1: { targetAxisIndex: 1 }
},
vAxes: {
0: {
},
1: {
},
}
};
var chart = new google.visualization.LineChart(
document.getElementById('chart_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);
}
}
});
}
}
function transpose(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;
};
}
SellsSumupClientDashBoardController.$inject = ['$scope', '$http', '$location', '$state', '$timeout', '$window', 'shApi', 'CanonicalUrl', 'Translator', 'Validations', 'ClientDashboard'];
var TravelAgentLockOrderController = function ($scope, $http, $location, $state, $timeout, $window, shApi, CanonicalUrl, Translator, AntiForgery) {
$scope.initialize = function (orderData, needLockCheckStatus) {
$scope.Model = {};
$scope.Model.culture = Translator.getCurrentCulture();
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
$scope.Model.showSendPaymentLink = false;
$scope.Model.showPaymentLinkSendConfirmation = false;
shApi.interceptor25x($scope, $scope.Model);
shApi.interceptor40x($scope, $scope.Model);
//MODALS
shApi.navigationStateControl($scope.Model);
//FORM ERROR
shApi.defineRequired($scope, $scope.Model);
$scope.Model.orderData = orderData;
$scope.Model.lockingServices = false;
$scope.Model.showAlerts = {};
$scope.Model.needLockCheckStatus = needLockCheckStatus;
AntiForgery.getAntiForgery($scope.Model.prefix).then(function (tok) {
$scope.Model.Token = tok;
if ($scope.Model.orderData.LockStatus == $scope.Model.needLockCheckStatus) {
checkAvailability($scope.Model.orderData.OrderCode);
}
});
$scope.Model.isLockOrderKO = false;
angular.forEach($scope.Model.orderData.BookingPackages, function (lockOrderKO, key) {
if (lockOrderKO.LockData != null ) {
if (lockOrderKO.LockData.LockStatus == "KO") {
$scope.Model.isLockOrderKO = true;
}
}
});
}
$scope.openSendPaymentLink = function (e, type) {
$('html').css('overflow', 'hidden');
$scope.Model.showSendPaymentLink = true;
};
$scope.closeSendPaymentLink = function () {
$scope.Model.showSendPaymentLink = false;
$('html').css('overflow', 'auto');
};
$scope.openPaymentLinkSendConfirmation = function (e, type) {
$('html').css('overflow', 'hidden');
$scope.Model.showPaymentLinkSendConfirmation = true;
};
$scope.closePaymentLinkSendConfirmation = function () {
$scope.Model.showPaymentLinkSendConfirmation = false;
$('html').css('overflow', 'auto');
};
$scope.copyToClipboard = function (link) {
navigator.clipboard.writeText(link);
};
$scope.sendPurchaseEmail = function (e) {
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'partner-send-email-purchase-ag'), {
orderCode: $scope.Model.orderData.OrderCode,
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
}).success(function (data, status, headers, config) {
$scope.closeSendPaymentLink();
$scope.openPaymentLinkSendConfirmation();
}).error(function (data, status, headers, config) {
shApi.handleError($scope.Model, Translator.getTranslation('modal_error_text'), false, false);
});
};
$scope.confirmDeferredOrder = function (e) {
};
$scope.showCartDetail = function (e, id) {
if (shApi.preventNavigate(e, $scope.Model)) return;
$scope.Model.showingIndex = id;
}
function checkAvailability(orderCode) {
$scope.Model.lockingServices = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-check-order-availability-ag'), {
orderCode: orderCode,
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
}).success(function (data, status, headers, config) {
$scope.Model.lockingServices = false;
$scope.Model.orderData = data;
}).error(function (data, status, headers, config) {
$scope.Model.lockingServices = false;
shApi.handleError($scope.Model, Translator.getTranslation('modal_error_text') + 'Id: ' + $scope.Model.orderData.TransactionId + '
', false, false);
});
};
//Voucher modal
$scope.openVoucherModal = function (e, order) {
if (e != undefined) { if (shApi.preventNavigate(e, $scope.Model)) return; };
$scope.Model.voucherOK = false;
$scope.Model.loadingVoucher = true;
$scope.Model.showVoucherOrderModal = true;
$scope.Model.voucherData = null;
$scope.downloadVoucher(e);
}
$scope.downloadVoucher = function (e) {
if (e != undefined) { if (shApi.preventNavigate(e, $scope.Model)) return; };
if ($scope.Model.voucherData == null) {
$scope.Model.loadingVoucher = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-get-voucher-ag'), {
token: $scope.Model.orderData.VoucherToken
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
if (status == 253 || data == null) {
$scope.Model.voucherError = true;
}
else {
$scope.Model.voucherData = data;
$scope.Model.voucherOK = true;
shApi.getPdfFile($scope.Model.voucherData, $scope.Model.orderData.OrderCode);
}
$scope.Model.loadingVoucher = false;
})
.error(function (data, status, headers, config) {
$scope.Model.loadingVoucher = false;
shApi.handleError($scope.Model, Translator.getTranslation('modal_error_text'), false, false);
});
}
else {
shApi.getPdfFile($scope.Model.voucherData, $scope.Model.orderData.OrderCode);
$scope.Model.voucherOK = true;
$scope.Model.loadingVoucher = false;
}
}
$scope.closeVoucherModal = function (e) {
if (e != undefined) { if (shApi.preventNavigate(e, $scope.Model)) return; };
$scope.Model.showVoucherOrderModal = false;
$scope.Model.voucherOK = false;
$scope.Model.loadingVoucher = false;
$scope.Model.voucherError = false;
$scope.Model.voucherData = null;
}
$scope.openContactForm = function (e, type) {
$('html').css('overflow', 'hidden');
$scope.Model.contact = {};
$scope.Model.contacted = false;
$scope.Model.showContactForm = true;
};
$scope.closeContactForm = function () {
$scope.Model.showContactForm = false;
$('html').css('overflow', 'auto');
};
$scope.saveHitContact = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
if ($scope.Model.contactForm.$valid && $scope.Model.contact.anonymousMsg != '') {
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-contact-city-hit-error-lock-ag'), {
notes: $scope.Model.contact.anonymousMsg,
orderCode: $scope.Model.orderData.OrderCode
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.contacted = true;
$scope.Model.pageError = null;
if (data != 'true') {
shApi.handleError($scope.Model, data, true);
}
})
.error(function (data, status, headers, config) {
shApi.handleError($scope.Model, Translator.getTranslation('modal_error_text'), false, false);
});
} else {
$scope.Model.continue = true;
$window.setTimeout(function () { shApi.scrollToError($scope.Model.topIntegrationOffset); }, 350);
}
};
//////
}
TravelAgentLockOrderController.$inject = ['$scope', '$http', '$location', '$state', '$timeout', '$window', 'shApi', 'CanonicalUrl', 'Translator', 'AntiForgery'];
var TravelAgentOrderDetailDashboardController = function ($scope, $http, $state, shApi, CanonicalUrl, Translator, AntiForgery, $window) {
$scope.initialize = function (orderData, clientData, refundData) {
$scope.Model = {};
AntiForgery.getAntiForgery($scope.Model.prefix).then(function (tok) { $scope.Model.Token = tok; });
$scope.Model.clientData = clientData;
$scope.Model.orderData = orderData;
$scope.Model.showAlerts = {};
$scope.Model.continue = false;
$scope.Model.culture = Translator.getCurrentCulture();
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
$scope.Model.showEditExternalReference = false;
// If future show edit external reference button
var currentTime = new Date();
var orderEndDate = new Date($scope.Model.orderData.endDate);
if ( orderEndDate.getTime() > currentTime.getTime() ) {
$scope.Model.showEditExternalReference = true;
}
// ------
$scope.Model.RefundStatusInfo = null;
if (refundData != null) {
$scope.Model.RefundStatusInfo = refundData.refundStatus;
}
// ------
shApi.interceptor25x($scope, $scope.Model);
shApi.interceptor40x($scope, $scope.Model);
//MODALS
shApi.navigationStateControl($scope.Model);
//FORM ERROR
shApi.defineRequired($scope, $scope.Model);
$scope.Model.isChauffeur = false;
$scope.Model.status = null;
$state.go('agent-dashboard-travel-agent-order-details-info', { pre: CanonicalUrl.getFolderPrefix($scope.Model.culture), targeturl: 'agent-dashboard-travel-agent-order-details-info' });
}
$scope.retryOrderLock = function (e, isDeferred) {
if (shApi.preventNavigate(e, $scope.Model)) return;
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-change-order-retry-lock-ag'), {
orderCode: $scope.Model.orderData.orderCode,
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
if (status == 251) {
if (isDeferred) {
$window.location.href = CanonicalUrl.getUrl($scope.Model.culture, 'agent-order-confirmation/') + $scope.Model.orderData.lockToken;
}
else {
$scope.openPaymentLinkModal(e);
}
}
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
});
}
$scope.goToPaymentLink = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
window.open($scope.Model.orderData.paymentUrl, '_blank');
}
$scope.sendPurchaseEmail = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
var order = $scope.Model.orderData;
$scope.Model.working = true;
if (order != null) {
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'partner-send-email-purchase-ag'), {
orderCode: order.orderCode,
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
}).success(function (data, status, headers, config) {
$scope.Model.working = false;
}).error(function (data, status, headers, config) {
shApi.handleError($scope.Model.culture, data);
$scope.Model.working = false;
});
}
}
//Payment link modal
$scope.openPaymentLinkModal = function (e) {
if (e != undefined) { if (shApi.preventNavigate(e, $scope.Model)) return; };
$scope.Model.url = $scope.Model.orderData.paymentUrl;
$scope.Model.showPaymentLinkOrderModal = true;
};
$scope.closePaymentLinkModal = function () {
$scope.Model.showPaymentLinkOrderModal = false;
$scope.Model.url = null;
};
$scope.copyToClipboard = function () {
shApi.copyToClipboard(document.getElementById("orderPaymentUrl"));
}
$scope.openUrl = function (link) {
window.open(link, '_blank');
}
$scope.getUpdatedOrderData = function () {
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-dashboard-travel-agent-order-details-info-updated-ag'), {
orderCode: $scope.Model.orderData.orderCode,
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
}).success(function (data, status, headers, config) {
$scope.Model.orderData = data;
$scope.Model.working = false;
}).error(function (data, status, headers, config) {
$scope.Model.working = false;
shApi.handleError($scope.Model.culture, data);
});
}
//Change to payment pending
$scope.changeToPaymentPending = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-change-order-to-payment-pending-ag'), {
orderCode: $scope.Model.orderData.orderCode,
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
if (status == 251) {
$scope.Model.working = false;
$scope.getUpdatedOrderData();
$scope.openPaymentLinkModal(e, $scope.Model.orderData.paymentUrl);
}
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
});
}
//Cancellation modal
$scope.openCancelationModal = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
$scope.Model.showCancelOrderModal = true;
$scope.Model.cancelationCode = null;
}
$scope.closeCancelationModal = function () {
$scope.Model.showCancelOrderModal = false;
$scope.Model.cancelationCode = null;
};
$scope.cancelOrder = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
if ($scope.Model.orderListForm.$valid) {
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-cancel-order-ag'), {
orderCode: $scope.Model.orderData.orderCode,
cancelationCode: $scope.Model.cancelationCode
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.closeCancelationModal();
$scope.getUpdatedOrderData();
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
$scope.closeCancelationModal();
});
}
else
$scope.Model.continue = true;
}
// Edit External Reference Modal
$scope.openEditExternalReferenceModal = function (e) {
$scope.Model.showEditExternalRefenreceModal = true;
$scope.Model.modalEditExternalReference = {};
$scope.Model.modalEditExternalReference.newExternalReference = null;
$scope.Model.modalEditExternalReference.orderCode = $scope.Model.orderData.orderCode;
}
$scope.editExternalReference = function () {
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-edit-external-reference'),
{
orderCode: $scope.Model.modalEditExternalReference.orderCode,
newexternalreference: $scope.Model.modalEditExternalReference.newExternalReference
},
{
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.getUpdatedOrderData();
$scope.Model.showEditExternalRefenreceModal = false;
$scope.Model.modalEditExternalReference = {};
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
$scope.Model.showEditExternalRefenreceModal = false;
});
}
// ---------------------------------
//Voucher modal
$scope.openVoucherModal = function (e, order) {
if (e != undefined) { if (shApi.preventNavigate(e, $scope.Model)) return; };
$scope.Model.voucherOK = false;
$scope.Model.loadingVoucher = true;
$scope.Model.showVoucherOrderModal = true;
$scope.Model.voucherData = null;
$scope.downloadVoucher(e);
}
$scope.downloadVoucher = function (e) {
if (e != undefined) { if (shApi.preventNavigate(e, $scope.Model)) return; };
if ($scope.Model.voucherData == null) {
$scope.Model.loadingVoucher = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-get-voucher-ag'), {
token: $scope.Model.orderData.voucherToken
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
if (status == 253 || data == null) {
$scope.Model.voucherError = true;
}
else {
$scope.Model.voucherData = data;
$scope.Model.voucherOK = true;
shApi.getPdfFile($scope.Model.voucherData, $scope.Model.orderData.orderCode);
}
$scope.Model.loadingVoucher = false;
})
.error(function (data, status, headers, config) {
$scope.Model.loadingVoucher = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
});
}
else {
shApi.getPdfFile($scope.Model.voucherData, $scope.Model.orderData.orderCode);
$scope.Model.voucherOK = true;
$scope.Model.loadingVoucher = false;
}
}
$scope.closeVoucherModal = function (e) {
if (e != undefined) { if (shApi.preventNavigate(e, $scope.Model)) return; };
$scope.Model.showVoucherOrderModal = false;
$scope.Model.voucherOK = false;
$scope.Model.loadingVoucher = false;
$scope.Model.voucherError = false;
$scope.Model.voucherData = null;
}
//////
}
TravelAgentOrderDetailDashboardController.$inject = ['$scope', '$http', '$state', 'shApi', 'CanonicalUrl', 'Translator', 'AntiForgery', '$window'];
var TravelAgentOrdersListDashboardController = function ($scope, $http, $location, $state, $timeout, ClientDashboard, CanonicalUrl, Translator, shApi, $window, Lookups, AntiForgery) {
var from = null;
var to = null;
$scope.initialize = function (ordersListDateFilter, filterOption, filterOrderCode, filterEmail, filterCountry, filterService, filterDateFrom, filterDateTo, applyFilters) {
$scope.Model = {};
$scope.Model.count = -1;
$scope.Model.totalPages = 0;
$scope.Model.working = false;
$scope.Model.culture = Translator.getCurrentCulture();
$scope.Model.prefix = shApi.getPrefix($scope.Model.culture);
$scope.Model.timezoneOffset = shApi.getTimezoneOffset();
$scope.Model.orderChecked = 0;
$scope.Model.stopWatcher = false;
$scope.Model.filters = {}; // Data from the filter search modal
$scope.Model.applyFilters = JSON.parse(applyFilters.toLowerCase());
$scope.Model.showFiltersModal = false;
$scope.Model.formSend = false;
$scope.Model.selectedOrders = [];
$scope.Model.ordersListDateFilter = ordersListDateFilter;
var recentFilter = []; recentFilter.key = "Recent"; recentFilter.value = "Recent";
$scope.Model.ordersListDateFilter.unshift(recentFilter);
angular.forEach($scope.Model.ordersListDateFilter, function (value, key) {
if (value.key == 'NextOrders')
$scope.Model.dateFilterDefault = value;
});
//Reservas futuras por defecto en filtro
if ($scope.Model.dateFilterDefault != undefined && $scope.Model.dateFilterDefault != null)
$scope.Model.bookingDetailSelector = $scope.Model.dateFilterDefault.key;
$scope.Model.from = shApi.serverUTCDateFromTime(new Date().getTime());
$scope.Model.to = shApi.serverUTCDateFromTime(new Date().getTime());
if ($scope.Model.applyFilters) {
$scope.applyFilters(filterOption, filterOrderCode, filterEmail, filterCountry, filterService, filterDateFrom, filterDateTo);
}
//MODALS
shApi.navigationStateControl($scope.Model);
//FORM ERROR
shApi.defineRequired($scope, $scope.Model);
shApi.interceptor25x($scope, $scope.Model);
shApi.interceptor40x($scope, $scope.Model);
shApi.interceptor55x($scope, $scope.Model);
shApi.timeout($scope);
AntiForgery.getAntiForgery($scope.Model.prefix).then(function (tok) {
$scope.Model.Token = tok;
$scope.switchpage(1);
});
$scope.filtersSelected();
}
//obtiene ciudades
$scope.getCities = function (filter) {
return Lookups.getAllCities(filter, $scope.Model.prefix)
.then(function (response) {
return response;
});
};
//obtiene los paises
$scope.getCountries = function (filter) {
return Lookups.getCountries(filter, $scope.Model.prefix)
.then(function (response) {
return response;
});
};
$scope.switchpage = function (type) {
$scope.Model.working = true;
if (type == 1)
$scope.Model.count = $scope.Model.count + 1;
else if (type == 0)
$scope.Model.count = $scope.Model.count - 1;
else if (type == 2) {
$scope.Model.count = $scope.Model.totalPages - 1;
}
else if (type == 3) {
$scope.Model.count = 0;
}
if ($scope.Model.bookingDetailSelector == 'OrdersBetweenDates' && $scope.Model.from != null && $scope.Model.to != null) {
from = $scope.Model.from.toISOString();
to = $scope.Model.to.toISOString();
}
$scope.getPagedOrdersList();
}
$scope.applyModalFilters = function (e) {
$scope.Model.formSend = true;
if ( $scope.Model.orderFilters.$dirty || e == "tag" || e == "date" && $scope.Model.bookingDetailSelector == "OrdersBetweenDates" ) {
$scope.Model.showFiltersModal = false;
$scope.search(e);
$scope.Model.orderFilters.$setPristine();
$scope.Model.orderFilters.$setUntouched();
}
}
$scope.search = function (e) {
$scope.Model.count = 0;
$scope.Model.totalPages = 0;
$scope.Model.working = true;
if ($scope.Model.bookingDetailSelector == 'OrdersBetweenDates' && $scope.Model.from != null && $scope.Model.to != null) {
from = $scope.Model.from.toISOString();
to = $scope.Model.to.toISOString();
}
$scope.getPagedOrdersList(true);
};
$scope.$watch('Model.from', function (newVal, oldVal) {
if (newVal !== oldVal && $scope.Model.stopWatcher == false) {
$scope.applyModalFilters('date')
}
});
$scope.$watch('Model.to', function (newVal, oldVal) {
if (newVal !== oldVal && $scope.Model.stopWatcher == false) {
$scope.applyModalFilters('date')
}
});
$scope.$watchGroup(['Model.filters.searchOrderCode', 'Model.filters.searchEmail', 'Model.filters.searchCountry', 'Model.filters.searchService'], function(newValues, oldValues, scope) {
if (newValues != oldValues) {
$scope.filtersSelected();
}
});
$scope.filtersSelected = function () {
var searchOrderCode = 0; var searchEmail = 0; var searchCountry = 0; var searchService = 0;
if ($scope.Model.filters.searchOrderCode != undefined && $scope.Model.filters.searchOrderCode != null && $scope.Model.filters.searchOrderCode != "") {searchOrderCode = 1;}
if ($scope.Model.filters.searchEmail != undefined && $scope.Model.filters.searchEmail != null && $scope.Model.filters.searchEmail != "") {searchEmail = 1;}
if ($scope.Model.filters.searchCountry != undefined && $scope.Model.filters.searchClientName != null && $scope.Model.filters.searchClientName != "") {searchClientName = 1;}
if ($scope.Model.filters.searchService != undefined && $scope.Model.filters.searchService != null && $scope.Model.filters.searchService != "") {searchService = 1;}
$scope.Model.tagsSelected = searchOrderCode + searchEmail + searchCountry + searchService;
}
$scope.clearFilters = function () {
$scope.Model.filters.searchOrderCode = null;
$scope.Model.filters.searchEmail = null;
$scope.Model.filters.searchCountry = null;
$scope.Model.filters.searchService = null;
$scope.Model.bookingDetailSelector = "NextOrders";
$scope.getPagedOrdersList();
};
$scope.getPagedOrdersList = function (isSearch) {
var city = $scope.Model.searchCity;
var idCity;
if (city != undefined && city != null) {
if (city.IdCity != undefined && city.IdCity != null)
idCity = city.IdCity;
}
var countryCode = null;
if ($scope.Model.filters.searchCountry != undefined && $scope.Model.filters.searchCountry != null)
countryCode = $scope.Model.filters.searchCountry.Code;
ClientDashboard.getPagedOrdersList($scope.Model.count, $scope.Model.prefix, $scope.Model.Token, $scope.Model.bookingDetailSelector, from, to,
$scope.Model.filters.searchEmail, $scope.Model.filters.searchOrderCode, $scope.Model.transactionId, $scope.Model.orderStatus, idCity, countryCode, $scope.Model.filters.searchService, isSearch)
.then(function (response) {
$scope.Model.orders = response.data.orders;
$scope.Model.totalPages = response.data.pages;
$scope.Model.working = false;
angular.forEach($scope.Model.orders, function (order, key) {
angular.forEach(order.Packages, function (packages, key) {
if(packages.Services[0] != null) {
order.RefundStatusInfo = packages.Services[0].RefundStatus;
}
});
});
from = null;
to = null;
$scope.Model.stopWatcher = false;
});
}
$scope.applyFilters = function (filterOption, filterOrderCode, filterEmail, filterCountry, filterService, filterDateFrom, filterDateTo) {
$scope.Model.stopWatcher = true;
$scope.Model.bookingDetailSelector = filterOption;
$scope.Model.filters.searchOrderCode = filterOrderCode;
$scope.Model.filters.searchEmail = filterEmail;
$scope.Model.filters.searchCountry = filterCountry;
$scope.Model.filters.searchService = filterService;
//$scope.Model.from = filterDateFrom;
//$scope.Model.to = filterDateTo;
if (filterDateFrom > 0) {
$scope.Model.from = shApi.getUTCDateFromTime(filterDateFrom);
} else {
$scope.Model.from = null;
}
if (filterDateTo > 0) {
$scope.Model.to = shApi.getUTCDateFromTime(filterDateTo);
} else {
$scope.Model.to = null;
}
}
$scope.$watch('Model.bookingDetailSelector', function (newValue, oldValue) {
if (newValue == 'OrdersBetweenDates' && $scope.Model.from > $scope.Model.to)
return;
if (newValue != oldValue) {
$scope.Model.bookingDetailSelector = newValue;
$scope.search();
}
});
$scope.check = function (order) {
order.checked ? $scope.Model.orderChecked++ : $scope.Model.orderChecked--;
$scope.Model.selectedOrders = $scope.Model.orders.filter(isChecked);
}
function isChecked(order) {
return order.checked;
}
//Cancel order in modal window
$scope.openCancelationModal = function (order) {
$scope.Model.showCancelOrderModal = true;
$scope.Model.orderToCancel = null;
$scope.Model.cancelationCode = null;
if (order != null) {
$scope.Model.orderToCancel = order;
} else {
var orders = $scope.Model.orders.filter(isChecked);
if (orders != null && orders.length == 1) {
$scope.Model.orderToCancel = orders[0];
} else {
$scope.Model.errorMsg = Translator.getTranslation('modal_error');
$scope.Model.error = true;
}
}
}
//Cancellation modal
$scope.closeCancelationModal = function () {
$scope.Model.showCancelOrderModal = false;
$scope.Model.orderToCancel = null;
$scope.Model.cancelationCode = null;
};
$scope.cancelOrder = function (e) {
if (shApi.preventNavigate(e, $scope.Model)) return;
if ($scope.Model.orderListForm.$valid) {
$scope.Model.working = true;
var order = $scope.Model.orderToCancel;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-cancel-order-ag'), {
orderCode: order.OrderCode,
cancelationCode: $scope.Model.cancelationCode
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.getPagedOrdersList();
$scope.closeCancelationModal();
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
$scope.closeCancelationModal();
});
}
else
$scope.Model.continue = true;
}
// Edit External Reference Modal
$scope.openEditExternalReferenceModal = function (order) {
$scope.Model.showEditExternalRefenreceModal = true;
$scope.Model.modalEditExternalReference = {};
$scope.Model.modalEditExternalReference.newExternalReference = null;
$scope.Model.modalEditExternalReference.orderCode = order.OrderCode;
}
$scope.editExternalReference = function () {
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-edit-external-reference'),
{
orderCode: $scope.Model.modalEditExternalReference.orderCode,
newexternalreference: $scope.Model.modalEditExternalReference.newExternalReference
},
{
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.getPagedOrdersList();
$scope.Model.showEditExternalRefenreceModal = false;
$scope.Model.modalEditExternalReference = {};
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
$scope.Model.showEditExternalRefenreceModal = false;
});
}
// ---------------------------------
$scope.changeToPaymentPending = function (e, orderCode, paymentLink) {
if (shApi.preventNavigate(e, $scope.Model)) return;
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-change-order-to-payment-pending-ag'), {
orderCode: orderCode,
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
if (status == 251) {
$scope.getPagedOrdersList();
$scope.openPaymentLinkModal(e, paymentUrl);
}
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
});
}
$scope.retryOrderLock = function (e, orderCode, lockToken, paymentUrl, isDeferred) {
if (shApi.preventNavigate(e, $scope.Model)) return;
$scope.Model.working = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-change-order-retry-lock-ag'), {
orderCode: orderCode,
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
if (status == 251) {
$scope.getPagedOrdersList();
if (isDeferred) {
$window.location.href = CanonicalUrl.getUrl($scope.Model.culture, 'agent-order-confirmation/') + lockToken;
}
else {
$scope.openPaymentLinkModal(e, paymentUrl);
}
}
})
.error(function (data, status, headers, config) {
$scope.Model.working = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
});
}
$scope.checkFlag = function (value, flag) {
return value & flag;
}
//Payment Link modal
$scope.openPaymentLinkModal = function (e, paymentUrl) {
if (e != undefined) { if (shApi.preventNavigate(e, $scope.Model)) return; };
$scope.Model.url = paymentUrl;
$scope.Model.showPaymentLinkOrderModal = true;
};
$scope.closePaymentLinkModal = function () {
$scope.Model.showPaymentLinkOrderModal = false;
$scope.Model.url = null;
};
$scope.copyToClipboard = function () {
shApi.copyToClipboard(document.getElementById("orderPaymentUrl"));
}
$scope.openUrl = function (link) {
window.open(link, '_blank');
}
/////////////
//Voucher modal
$scope.openVoucherModal = function (e, order) {
if (e != undefined) { if (shApi.preventNavigate(e, $scope.Model)) return; };
$scope.Model.voucherOK = false;
$scope.Model.loadingVoucher = true;
$scope.Model.showVoucherOrderModal = true;
$scope.Model.voucherData = null;
$scope.Model.currentOrder = order;
$scope.downloadVoucher(e);
}
$scope.downloadVoucher = function (e) {
if (e != undefined) { if (shApi.preventNavigate(e, $scope.Model)) return; };
if ($scope.Model.voucherData == null) {
$scope.Model.loadingVoucher = true;
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'agent-get-voucher-ag'), {
token: $scope.Model.currentOrder.VoucherToken
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
})
.success(function (data, status, headers, config) {
$scope.Model.working = false;
if (status == 253 || data == null) {
$scope.Model.voucherError = true;
}
else {
$scope.Model.voucherData = data;
$scope.Model.voucherOK = true;
shApi.getPdfFile($scope.Model.voucherData, $scope.Model.currentOrder.OrderCode);
}
$scope.Model.loadingVoucher = false;
})
.error(function (data, status, headers, config) {
$scope.Model.loadingVoucher = false;
$scope.Model.errorMsg = Translator.getTranslation('error_server_connection');
});
}
else {
shApi.getPdfFile($scope.Model.voucherData, $scope.Model.currentOrder.OrderCode);
$scope.Model.voucherOK = true;
$scope.Model.loadingVoucher = false;
}
}
$scope.closeVoucherModal = function (e) {
if (e != undefined) { if (shApi.preventNavigate(e, $scope.Model)) return; };
$scope.Model.showVoucherOrderModal = false;
$scope.Model.voucherOK = false;
$scope.Model.loadingVoucher = false;
$scope.Model.voucherError = false;
$scope.Model.voucherData = null;
$scope.Model.currentOrder = null;
}
//////
$scope.sendPurchaseEmail = function (order) {
if (order != null) {
$http.post(CanonicalUrl.getUrl($scope.Model.culture, 'partner-send-email-purchase-ag'), {
orderCode: order.OrderCode,
}
, {
headers: {
'__RequestVerificationToken': $scope.Model.Token
}
}).success(function (data, status, headers, config) {
}).error(function (data, status, headers, config) {
shApi.handleError($scope.Model.culture, data);
});
}
}
$scope.getDetails = function (e,order) {
if (shApi.preventNavigate(e, $scope.Model)) return;
$scope.Model.working = true;
var orderCode = order.OrderCode;
$window.location.href = CanonicalUrl.getUrl($scope.Model.culture, 'agent-dashboard-travel-agent-order-detail/') + orderCode;
}
function getOrderCode(item, index) {
return item.OrderCode;
}
}
TravelAgentOrdersListDashboardController.$inject = ['$scope', '$http', '$location', '$state', '$timeout', 'ClientDashboard', 'CanonicalUrl', 'Translator', 'shApi', '$window', 'Lookups', 'AntiForgery'];
var ServantripClientMVCApp = angular.module('ServantripClientMVCApp', ['ui.router', 'ui.router.util',
'ui.bootstrap', 'ui.bootstrap.datepicker',
'ngFileUpload', 'ngLazyImage', 'ui.bootstrap.typeahead', 'ui.slider', 'ngLookupsService', 'ngValidationsService',
'checklist-model', 'ngCanonicalUrlService', 'angular-carousel',
'ngTranslator', 'ngSharedDirectives', 'ngDynamicFormRender', 'ngClientDashboardService', 'ngSharedApi',
'ngAntiForgeryService', 'ngCookies', 'ngSharedPurchase', 'ngPurchasesService', 'ngSharedCheckout', 'ngChartsService','ui.bootstrap.timepicker']);
ServantripClientMVCApp.controller('AgentLoginController', AgentLoginController);
ServantripClientMVCApp.controller('ClientLoginController', ClientLoginController);
ServantripClientMVCApp.controller('ClientDashboardController', ClientDashBoardController);
//ServantripClientMVCApp.controller('ClientDashboardUserProfileController', ClientDashboardUserProfileController);
ServantripClientMVCApp.controller('AgentEditDetailsController', AgentEditDetailsController);
ServantripClientMVCApp.controller('ClientDashboardOrderDetailController', ClientDashboardOrderDetailController);
ServantripClientMVCApp.controller('TravelAgentOrdersListDashboardController', TravelAgentOrdersListDashboardController);
ServantripClientMVCApp.controller('ClientOrderApprovingListDashBoardController', ClientOrderApprovingListDashBoardController);
ServantripClientMVCApp.controller('SellsSumupClientDashBoardController', SellsSumupClientDashBoardController);
ServantripClientMVCApp.controller('UserPurchaseController', UserPurchaseController);
ServantripClientMVCApp.controller('ClientOrderFilteredController', ClientOrderFilteredController);
ServantripClientMVCApp.controller('ClientDashboardKPIController', ClientDashboardKPIController);
ServantripClientMVCApp.controller('TravelAgentOrderDetailDashboardController', TravelAgentOrderDetailDashboardController);
//ServantripClientMVCApp.controller('ClientDashboardOrderListController', ClientDashboardOrderListController);
ServantripClientMVCApp.controller('UserPurchaseBookingConfigurationController', UserPurchaseBookingConfigurationController);
ServantripClientMVCApp.controller('TravelAgentLockOrderController', TravelAgentLockOrderController);
ServantripClientMVCApp.controller('ClientDashboardSalesViewerController', ClientDashboardSalesViewerController);
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('agent-account-login', {
url: $urlMatcherFactory.compile(":pre/{targeturl:theurl}"),
views: {
"agentloginContainer": {
templateUrl: function ($stateParams) {
var prefix = '';
if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
prefix = '/' + $stateParams.pre;
return prefix + '/agent-account-login-ag';
}
}
}
})
.state('client-account-login', {
url: $urlMatcherFactory.compile(":pre/{targeturl:theurl}"),
views: {
"clientloginContainer": {
templateUrl: function ($stateParams) {
var prefix = '';
if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
prefix = '/' + $stateParams.pre;
return prefix + '/client-account-login-ag';
}
}
}
})
.state('client-dashboard-order-detail', {
url: $urlMatcherFactory.compile(":pre/{targeturl:theurl}"),
views: {
"mainOrderDataContainer": {
templateUrl: function ($stateParams) {
var prefix = '';
if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
prefix = '/' + $stateParams.pre;
return prefix + '/client-dashboard-order-detail-ag';
}
}
}
})
.state('agent-dashboard-travel-agent-order-details-info', {
url: $urlMatcherFactory.compile(":pre/{targeturl:theurl}"),
views: {
"mainOrderDataContainer": {
templateUrl: function ($stateParams) {
var prefix = '';
if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
prefix = '/' + $stateParams.pre;
return prefix + '/agent-dashboard-travel-agent-order-details-info-ag';
}
}
}
})
.state('agent-booking-configuration', {
url: $urlMatcherFactory.compile(":pre/{targeturl:theurl}"),
views: {
"mainTravelManagerPurchaseContainer": {
templateUrl: function ($stateParams) {
var prefix = '';
if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
prefix = '/' + $stateParams.pre;
return prefix + '/agent-booking-configuration-ag';
}
}
}
})
.state('agent-booking-additional-configuration', {
url: $urlMatcherFactory.compile(":pre/{targeturl:theurl}"),
views: {
"mainTravelManagerPurchaseContainer": {
templateUrl: function ($stateParams) {
var prefix = '';
if (typeof $stateParams.pre !== 'undefined' && $stateParams.pre !== '')
prefix = '/' + $stateParams.pre;
return prefix + '/agent-booking-additional-configuration-ag';
}
}
}
})
;
}
configFunction.$inject = ['$stateProvider', '$urlRouterProvider', '$httpProvider', '$locationProvider', '$urlMatcherFactoryProvider'];
ServantripClientMVCApp.config(configFunction);
$(".fab-button").hide();
$(document).ready(function () {
$('[data-toggle="tooltip"]').tooltip(); //tooltip initialization
setTimeout(function () {
if ($('footer') != undefined && isVisible($('footer')))
setButtonPosition();
$(".fab-button").show();
$('html,body').animate({ scrollTop: 0 }, 'slow');
}, 1000);
$(window).scroll(setButtonPosition);
$(window).resize(setButtonPosition);
});
function isVisible(element) {
var vpH = $(window).height(),
st = $(window).scrollTop(),
ele = $(element);
if (ele == undefined || ele.offset() == undefined)
return false;
var y = ele.offset().top;
return y <= (vpH + st);
}
function getVisibleHeight(element) {
var scrollTop = $(this).scrollTop();
var scrollBot = scrollTop + $(this).height();
var elTop = element.offset().top;
var elBottom = elTop + element.outerHeight();
var visibleTop = elTop < scrollTop ? scrollTop : elTop;
var visibleBottom = elBottom > scrollBot ? scrollBot : elBottom;
return visibleBottom - visibleTop;
}
function setButtonPosition() {
if ($('footer') != undefined && isVisible($('footer'))) {
var height = getVisibleHeight($('footer'));
if ($('#rrss') != undefined && isVisible($('#rrss')))
height = height + getVisibleHeight($('#rrss'));
$('.fab-button').css('bottom', height);
}
else {
$('.fab-button').css('bottom', 0);
}
}
(function (){ var aa="\n//# sourceURL=",ba='