' +
'
' + $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 = '
';
}
if (typeof $scope.type !== 'undefined' && ($scope.type.toLowerCase() === 'warning')) {
strret = '
';
}
if (typeof $scope.type !== 'undefined' && $scope.type.toLowerCase() === 'question') {
strret = '
';
}
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($('
'));
modelCtrl.$parsers.unshift(function (inputValue) {
if (!imp) {
return inputValue;
}
else {
for (var i = 0; i < src.length; i++) {
if (src[i][key] == inputValue) {
return src[i];
}
}
}
});
modelCtrl.$formatters.unshift(function (keyvalue) {
var newvalue = null;
if (key != null) //Con campo key
{
if (keyvalue != undefined) {
for (var i = 0; i < src.length; i++) {
if (keyvalue[key] == src[i][key]) {
newvalue = src[i][key];
}
}
}
}
else {
newvalue = keyvalue;
}
modelCtrl.$setViewValue(newvalue);
element.val(newvalue);
return newvalue;
});
},
};
}]);
ngSharedDirectives.directive('ngEsc', function ($document) {
return {
restrict: 'A',
link: function (scope, element, attr) {
var handler = function (evt) {
var which = evt.which;
if (which == 27) {
scope.$apply(attr.ngEsc);
evt.preventDefault();
evt.stopPropagation();
}
};
//var cleanup = function () {
// $document.off('keydown keypress keyup', handler);
//};
$document.on('keydown keypress keyup', handler);
//element.on('$destroy', cleanup);
}
}
});
ngSharedDirectives.value('THROTTLE_MILLISECONDS', null);
ngSharedDirectives.directive('infiniteScroll', [
'$rootScope', '$window', '$timeout', 'THROTTLE_MILLISECONDS', function ($rootScope, $window, $timeout, THROTTLE_MILLISECONDS) {
return {
scope: {
infiniteScroll: '&',
infiniteScrollContainer: '=',
infiniteScrollDistance: '=',
infiniteScrollDisabled: '='
},
link: function (scope, elem, attrs) {
var changeContainer, checkWhenEnabled, container, handleInfiniteScrollContainer, handleInfiniteScrollDisabled, handleInfiniteScrollDistance, handler, immediateCheck, scrollDistance, scrollEnabled, throttle;
$window = angular.element($window);
scrollDistance = null;
scrollEnabled = null;
checkWhenEnabled = null;
container = null;
immediateCheck = true;
handler = function () {
var containerBottom, elementBottom, remaining, shouldScroll;
if (container === $window) {
containerBottom = container.height() + container.scrollTop();
elementBottom = elem.offset().top + elem.height();
} else {
containerBottom = container.height();
elementBottom = elem.offset().top - container.offset().top + elem.height();
}
remaining = elementBottom - containerBottom;
shouldScroll = remaining <= container.height() * scrollDistance + 1;
if (shouldScroll && scrollEnabled) {
return scope.infiniteScroll();
} else if (shouldScroll) {
return checkWhenEnabled = true;
}
};
throttle = function (func, wait) {
var later, previous, timeout;
timeout = null;
previous = 0;
later = function () {
var context;
previous = new Date().getTime();
$timeout.cancel(timeout);
timeout = null;
func.call();
return context = null;
};
return function () {
var now, remaining;
now = new Date().getTime();
remaining = wait - (now - previous);
if (remaining <= 0) {
clearTimeout(timeout);
$timeout.cancel(timeout);
timeout = null;
previous = now;
return func.call();
} else {
if (!timeout) {
return timeout = $timeout(later, remaining);
}
}
};
};
if (THROTTLE_MILLISECONDS != null) {
handler = throttle(handler, THROTTLE_MILLISECONDS);
}
scope.$on('$destroy', function () {
return container.off('scroll', handler);
});
handleInfiniteScrollDistance = function (v) {
return scrollDistance = parseInt(v, 10) || 0;
};
scope.$watch('infiniteScrollDistance', handleInfiniteScrollDistance);
handleInfiniteScrollDistance(scope.infiniteScrollDistance);
handleInfiniteScrollDisabled = function (v) {
scrollEnabled = !v;
if (scrollEnabled && checkWhenEnabled) {
checkWhenEnabled = false;
return handler();
}
};
scope.$watch('infiniteScrollDisabled', handleInfiniteScrollDisabled);
handleInfiniteScrollDisabled(scope.infiniteScrollDisabled);
changeContainer = function (newContainer) {
if (container != null) {
container.off('scroll', handler);
}
container = newContainer;
if (newContainer != null) {
return container.on('scroll', handler);
}
};
changeContainer($window);
handleInfiniteScrollContainer = function (newContainer) {
if ((!(newContainer != null)) || newContainer.length === 0) {
return;
}
newContainer = angular.element(newContainer);
if (newContainer != null) {
return changeContainer(newContainer);
} else {
throw new Exception("invalid infinite-scroll-container attribute.");
}
};
scope.$watch('infiniteScrollContainer', handleInfiniteScrollContainer);
handleInfiniteScrollContainer(scope.infiniteScrollContainer || []);
if (attrs.infiniteScrollParent != null) {
changeContainer(angular.element(elem.parent()));
}
if (attrs.infiniteScrollImmediateCheck != null) {
immediateCheck = scope.$eval(attrs.infiniteScrollImmediateCheck);
}
return $timeout((function () {
if (immediateCheck) {
return handler();
}
}), 0);
}
};
}
]);
ngSharedDirectives.directive('stRadiobuttonSelector', function () {
return {
restrict: 'E',
scope: {
model: '=',
options: '=',
mainoption: '@',
firstoption: '@',
alternativeoption: '@',
optionValue: '=',
mainClass: '@',
isOpen: '=',
disabled: '=',
},
link: function (scope, elem, attrs, ctrls) {
if (scope.fixed === undefined) scope.fixed = false;
if (scope.disabled === undefined) scope.disabled = false;
scope.isOpen = false;
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-dropdown-container');
var close = $(elem[0]).find('.js-save-button');
$(document).mouseup(function (e) {
if (!scope.fixed) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
if (!container.hasClass('hidden')) {
e.preventDefault();
close.trigger('click');
}
}
}
});
$(document).ready(function (e) {
button.click(function (e) {
if (container.hasClass('hidden')) {
if (!scope.disabled) {
container.removeClass('hidden');
scope.$apply(function () {
scope.isOpen = true;
});
}
}
else {
e.preventDefault();
close.trigger('click');
}
})
close.click(function (e) {
container.addClass('hidden');
scope.$apply(function () {
scope.isOpen = false;
});
});
});
/*TODO:Esto debe ser generico*/
scope.$watch('optionValue', function (newVal, oldVal) {
if (newVal != undefined && newVal != null) {
if (newVal) {
scope.selectedOption = 'option2';
scope.mainoption = scope.alternativeoption;
}
else {
scope.selectedOption = 'option1';
scope.mainoption = scope.firstoption;
}
}
else {
scope.mainoption = null;
scope.selectedOption = null;
}
});
scope.$watch('selectedOption', function (newVal, oldVal) {
if (newVal != oldVal) {
if (newVal == 'option2') {
scope.mainoption = scope.alternativeoption;
scope.optionValue = true;
}
else if (newVal == 'option1') {
scope.mainoption = scope.firstoption;
scope.optionValue = false;
}
container.addClass('hidden');
scope.isOpen = false;
}
});
},
templateUrl: '/Scripts/app/Modules/stRadiobuttonSelector.html'
};
});
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
ngSharedDirectives.directive('keyEnter', function () {
return function (scope, element, attrs) {
element.bind("keydown keypress", function (event) {
if (event.which === 13) {
scope.$apply(function () {
scope.$eval(attrs.keyEnter, { 'event': event });
});
event.preventDefault();
}
});
};
});
ngSharedDirectives.directive('starRating', [function () {
return {
restrict: 'A',
replace: true,
scope: {
starRating: '='
},
link:
function (scope, element, attrs) {
scope.$watch("starRating", function (newValue, oldValue) {
var val = parseFloat(newValue);
var size = Math.max(0, (Math.min(5, val))) * 16;
element[0].style.width = size + 'px';
element[0].style.backgroundPositionY = '0px';
});
}
}
}]);
ngSharedDirectives.directive('bsTooltip', function () {
return {
link: function (scope, element, attrs) {
$(element).hover(function () {
// on mouseenter
$(element).tooltip('show');
}, function () {
// on mouseleave
$(element).tooltip('hide');
});
}
};
});
ngSharedDirectives.directive('labelField', function () {
return {
restrict: 'AE',
link: function ($scope, element, attrs) {
$scope.$watch(attrs['ngModel'], function (newValue) {
if (newValue && typeof newValue[attrs['labelField']] != 'undefined') {
element[0].value = newValue[attrs['labelField']];
}
})
}
}
});
ngSharedDirectives.directive('bindHtmlCompile', ['$compile', function ($compile) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
scope.$watch(function () {
return scope.$eval(attrs.bindHtmlCompile);
}, function (value) {
// In case value is a TrustedValueHolderType, sometimes it
// needs to be explicitly called into a string in order to
// get the HTML string.
element.html(value && value.toString());
// If scope is provided use it, otherwise use parent scope
var compileScope = scope;
if (attrs.bindHtmlScope) {
compileScope = scope.$eval(attrs.bindHtmlScope);
}
$compile(element.contents())(compileScope);
});
}
};
}]);
ngSharedDirectives.factory('Cards', [function () {
var defaultFormat = /(\d{1,4})/g;
var defaultInputFormat = /(?:^|\s)(\d{4})$/;
var cards = [
{
type: 'maestro',
pattern: /^(5018|5020|5038|6304|6759|676[1-3])/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [12, 13, 14, 15, 16, 17, 18, 19],
cvcLength: [3],
luhn: true
}, {
type: 'dinersclub',
pattern: /^(36|38|30[0-5])/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [14],
cvcLength: [3],
luhn: true
}, {
type: 'laser',
pattern: /^(6706|6771|6709)/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [16, 17, 18, 19],
cvcLength: [3],
luhn: true
}, {
type: 'jcb',
pattern: /^35/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [16],
cvcLength: [3],
luhn: true
}, {
type: 'unionpay',
pattern: /^62/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [16, 17, 18, 19],
cvcLength: [3],
luhn: false
}, {
type: 'discover',
pattern: /^(6011|65|64[4-9]|622)/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [16],
cvcLength: [3],
luhn: true
}, {
type: 'mastercard',
pattern: /^5[1-5]/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [16],
cvcLength: [3],
luhn: true
}, {
type: 'amex',
pattern: /^3[47]/,
format: /(\d{1,4})(\d{1,6})?(\d{1,5})?/,
inputFormat: /^(\d{4}|\d{4}\s\d{6})$/,
length: [15],
cvcLength: [3, 4],
luhn: true
}, {
type: 'visa',
pattern: /^4/,
format: defaultFormat,
inputFormat: defaultInputFormat,
length: [13, 14, 15, 16],
cvcLength: [3],
luhn: true
}
];
var _fromNumber = function (num) {
var card, i, len;
num = (num + '').replace(/\D/g, '');
for (i = 0, len = cards.length; i < len; i++) {
card = cards[i];
if (card.pattern.test(num)) {
return card;
}
}
}
var _fromType = function (type) {
var card, i, len;
for (i = 0, len = cards.length; i < len; i++) {
card = cards[i];
if (card.type === type) {
return card;
}
}
};
return {
fromNumber: function (val) { return _fromNumber(val) },
fromType: function (val) { return _fromType(val) },
defaultFormat: function () { return defaultFormat; },
defaultInputFormat: function () { return defaultInputFormat; }
}
}])
.factory('_Format', ['Cards', '$filter', function (Cards, $filter) {
var _formats = {}
var _hasTextSelected = function ($target) {
var ref;
if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== $target.prop('selectionEnd')) {
return true;
}
if (typeof document !== "undefined" && document !== null ? (ref = document.selection) != null ? typeof ref.createRange === "function" ? ref.createRange().text : void 0 : void 0 : void 0) {
return true;
}
return false;
};
// card formatting
var _formatCardNumber = function (e) {
var $target, card, digit, length, re, upperLength, value;
digit = String.fromCharCode(e.which);
$target = angular.element(e.currentTarget);
value = $target.val();
card = Cards.fromNumber(value + digit);
length = (value.replace(/\D/g, '') + digit).length;
upperLength = 16;
if (card) {
upperLength = card.length[card.length.length - 1];
}
if (length >= upperLength) {
return;
}
if (!/^\d+$/.test(digit) && !e.meta && e.keyCode >= 46) {
e.preventDefault();
return;
}
if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== value.length) {
return;
}
re = Cards.defaultInputFormat();
if (card) {
re = card.inputFormat;
}
if (re.test(value)) {
e.preventDefault();
return $target.val(value + ' ' + digit);
} else if (re.test(value + digit)) {
e.preventDefault();
return $target.val(value + digit + ' ');
}
};
var _restrictCardNumber = function (e) {
var $target, card, digit, value;
$target = angular.element(e.currentTarget);
digit = String.fromCharCode(e.which);
if (!/^\d+$/.test(digit)) {
return;
}
if (_hasTextSelected($target)) {
return;
}
value = ($target.val() + digit).replace(/\D/g, '');
card = Cards.fromNumber(value);
if (card) {
if (!(value.length <= card.length[card.length.length - 1])) {
e.preventDefault();
}
} else {
if (!(value.length <= 16)) {
e.preventDefault();
}
}
};
var _formatBackCardNumber = function (e) {
var $target, value;
$target = angular.element(e.currentTarget);
value = $target.val();
if (e.meta) {
return;
}
if (e.which !== 8) {
return;
}
if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== value.length) {
return;
}
if (/\d\s$/.test(value) && !e.meta && e.keyCode >= 46) {
e.preventDefault();
return $target.val(value.replace(/\d\s$/, ''));
} else if (/\s\d?$/.test(value)) {
e.preventDefault();
return $target.val(value.replace(/\s\d?$/, ''));
}
};
var _getFormattedCardNumber = function (num) {
var card, groups, upperLength, ref;
card = Cards.fromNumber(num);
if (!card) {
return num;
}
upperLength = card.length[card.length.length - 1];
num = num.replace(/\D/g, '');
num = num.slice(0, +upperLength + 1 || 9e9);
if (card.format.global) {
return (ref = num.match(card.format)) != null ? ref.join(' ') : void 0;
} else {
groups = card.format.exec(num);
if (groups != null) {
groups.shift();
}
return groups != null ? groups.join(' ') : void 0;
}
};
var _reFormatCardNumber = function (e) {
return setTimeout(function () {
var $target, value;
$target = angular.element(e.target);
value = $target.val();
value = _getFormattedCardNumber(value);
return $target.val(value);
});
};
var _parseCardNumber = function (value) {
return value != null ? value.replace(/\s/g, '') : value;
};
_formats['card'] = function (elem, ctrl) {
elem.bind('keypress', _restrictCardNumber);
elem.bind('keypress', _formatCardNumber);
elem.bind('keydown', _formatBackCardNumber);
elem.bind('paste', _reFormatCardNumber);
ctrl.$parsers.push(_parseCardNumber);
ctrl.$formatters.push(_getFormattedCardNumber);
}
// cvc
_formatCVC = function (e) {
$target = angular.element(e.currentTarget);
digit = String.fromCharCode(e.which);
if (!/^\d+$/.test(digit) && !e.meta && e.keyCode >= 46) {
e.preventDefault();
return;
}
val = $target.val() + digit;
if (val.length <= 4) {
return;
} else {
e.preventDefault();
return;
}
}
_formats['cvc'] = function (elem) {
elem.bind('keypress', _formatCVC)
}
return function (type, elem, ctrl) {
if (!_formats[type]) {
types = Object.keys(_formats);
errstr = 'Unknown type for formatting: "' + type + '". ';
errstr += 'Should be one of: "' + types.join('", "') + '"';
throw errstr;
}
return _formats[type](elem, ctrl);
}
}])
.directive('paymentsFormat', ['$window', '_Format', function ($window, _Format) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, elem, attr, ctrl) {
_Format(attr.paymentsFormat, elem, ctrl);
}
}
}])
.factory('_Validate', ['Cards', '$parse', function (Cards, $parse) {
var __indexOf = [].indexOf || function (item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }
var _luhnCheck = function (num) {
var digit, digits, odd, sum, i, len;
odd = true;
sum = 0;
digits = (num + '').split('').reverse();
for (i = 0, len = digits.length; i < len; i++) {
digit = digits[i];
digit = parseInt(digit, 10);
if ((odd = !odd)) {
digit *= 2;
}
if (digit > 9) {
digit -= 9;
}
sum += digit;
}
return sum % 10 === 0;
};
var _validators = {}
_validators['cvc'] = function (cvc, ctrl, scope, attr) {
var ref, ref1;
// valid if empty - let ng-required handle empty
if (cvc == null || cvc.length == 0) return true;
if (!/^\d+$/.test(cvc)) {
return false;
}
var type;
if (attr.paymentsTypeModel) {
var typeModel = $parse(attr.paymentsTypeModel);
type = typeModel(scope);
}
if (type) {
return ref = cvc.length, __indexOf.call((ref1 = Cards.fromType(type)) != null ? ref1.cvcLength : void 0, ref) >= 0;
} else {
return cvc.length >= 3 && cvc.length <= 4;
}
}
_validators['card'] = function (num, ctrl, scope, attr) {
var card, ref, typeModel;
if (attr.paymentsTypeModel) {
typeModel = $parse(attr.paymentsTypeModel);
}
var clearCard = function () {
if (typeModel) {
typeModel.assign(scope, null);
}
ctrl.$card = null;
};
// valid if empty - let ng-required handle empty
if (num == null || num.length == 0) {
clearCard();
return true;
}
num = (num + '').replace(/\s+|-/g, '');
if (!/^\d+$/.test(num)) {
clearCard();
return false;
}
card = Cards.fromNumber(num);
if (!card) {
clearCard();
return false;
}
ctrl.$card = angular.copy(card);
if (typeModel) {
typeModel.assign(scope, card.type);
}
ret = (ref = num.length, __indexOf.call(card.length, ref) >= 0) && (card.luhn === false || _luhnCheck(num));
return ret;
}
return function (type, val, ctrl, scope, attr) {
if (!_validators[type]) {
types = Object.keys(_validators);
errstr = 'Unknown type for validation: "' + type + '". ';
errstr += 'Should be one of: "' + types.join('", "') + '"';
throw errstr;
}
return _validators[type](val, ctrl, scope, attr);
}
}])
.factory('_ValidateWatch', ['_Validate', function (_Validate) {
var _validatorWatches = {}
_validatorWatches['cvc'] = function (type, ctrl, scope, attr) {
if (attr.paymentsTypeModel) {
scope.$watch(attr.paymentsTypeModel, function (newVal, oldVal) {
if (newVal != oldVal) {
var valid = _Validate(type, ctrl.$modelValue, ctrl, scope, attr);
ctrl.$setValidity(type, valid);
}
});
}
}
return function (type, ctrl, scope, attr) {
if (_validatorWatches[type]) {
return _validatorWatches[type](type, ctrl, scope, attr);
}
}
}])
.directive('paymentsValidate', ['$window', '_Validate', '_ValidateWatch', function ($window, _Validate, _ValidateWatch) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, elem, attr, ctrl) {
var type = attr.paymentsValidate;
_ValidateWatch(type, ctrl, scope, attr);
var validateFn = function (val) {
var valid = _Validate(type, val, ctrl, scope, attr);
ctrl.$setValidity(type, valid);
return valid ? val : undefined;
};
ctrl.$formatters.push(validateFn);
ctrl.$parsers.push(validateFn);
}
}
}]);
ngSharedDirectives.directive('stPeopleSelector', function (shApi) {
return {
restrict: 'E',
scope: {
'people': '=',
'maxpeople': '=',
'adults': '=',
'childrenundertwelve': '=',
'childrenunderfive': '=',
'showoptions': '=',
'inputname': '@',
'inputmsg': '@',
'personmsg': '@',
'peoplemsg': '@',
'adultmsg': '@',
'adultsmsg': '@',
'childmsg': '@',
'childrenmsg': '@',
'babymsg': '@',
'babiesmsg': '@',
'infantmsg': "@",
'infantsmsg': "@",
'underfivemsg': '@',
'undertwelvemsg': '@',
'closemsg': '@',
'callbackOnClose': '=',
'mainClass': '@',
'isOpen': '=',
'allowrestablish': '=',
'originalpeople': '=',
'originaladults': '=',
'originalundertwelve': '=',
'originalunderfive': '=',
'unselectmsg': '@',
'disabled': '=',
'childseatalert': '=',
'childseatmessage': '@',
'filteralone': '=',
'required': '=',
'indicatepeople': '@',
'noadulterror': '@',
'isfirstsearch': '=',
'isclosed': '=',
},
link: function (scope, elem, attrs, ctrls) {
scope.isOpen = false;
if (scope.disabled === undefined) scope.disabled = false;
var close = $(elem[0]).find('.js-save-button');
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-dropdown-container');
var returnbutton = $(elem[0]).find('.js-return');
if (scope.filteralone == undefined || scope.filteralone == false) {
$(document).mouseup(function (e) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
if (!container.hasClass('hidden')) {
e.preventDefault();
close.trigger('click');
}
}
});
$(document).ready(function (e) {
close.click(function (e) {
container.addClass('hidden');
scope.isOpen = false;
shApi.fullWindow(false);
//callback execution to notify the directives that contain this directive
if (scope.callbackOnClose != undefined && scope.checkForChanges())
scope.callbackOnClose();
});
button.click(function (e) {
if (container.hasClass('hidden')) {
if (!scope.disabled) {
container.removeClass('hidden');
scope.$apply(function () {
scope.isOpen = true;
});
shApi.fullWindow(true);
//init default:
scope.initialValues();
}
} else {
//e.preventDefault();
close.trigger('click');
}
});
returnbutton.click(function (e) {
scope.return();
close.trigger('click');
});
})
}
},
controller: function ($scope) {
$scope.initialValues = function () {
$scope.initAdults = $scope.adults;
$scope.initChildrenUnderFive = $scope.originalunderfive;
$scope.initChildrenUnderTwelve = $scope.originalundertwelve;
$scope.initPeople = $scope.people;
}
//Restablish to before open step (reutrn button mobile only)
$scope.return = function () {
$scope.adults = $scope.initAdults;
$scope.childrenunderfive = $scope.initChildrenUnderFive;
$scope.childrenundertwelve = $scope.initChildrenUnderTwelve;
$scope.people = $scope.initPeople;
}
//Restablish to 0 step
$scope.restablish = function () {
if ($scope.allowrestablish) {
$scope.adults = $scope.originaladults;
$scope.childrenunderfive = $scope.originalunderfive;
$scope.childrenundertwelve = $scope.originalundertwelve;
$scope.people = $scope.originalpeople;
}
}
$scope.checkForChanges = function () {
var changes = false;
if ($scope.adults !== $scope.initAdults || $scope.childrenunderfive !== $scope.initChildrenUnderFive
|| $scope.childrenundertwelve !== $scope.initChildrenUnderTwelve) changes = true;
return changes;
}
$scope.addPeople = function (adult, undertwelve, underfive) {
if (adult != 0) {
$scope.adults += adult;
$scope.people += adult;
}
if (undertwelve != 0) {
$scope.childrenundertwelve += undertwelve;
$scope.people += undertwelve;
}
if (underfive != 0) {
$scope.childrenunderfive += underfive;
$scope.people += underfive;
}
}
$scope.showHideDropdown = function () {
$scope.isclosed = !$scope.isclosed;
}
},
templateUrl: '/Scripts/app/Modules/stPeopleSelectorTemplate.html'
}
});
ngSharedDirectives.directive('stDoubleSelector', function (Translator, shApi) {
var mandatoryData = false;
return {
restrict: 'E',
scope: {
'className': '@',
'mainClass': '@',
'mainItem': '=',
'mainItemKey': '=',
'mainItemName': '@',
'mainOptionList': '=',
'numItemsKey': '=',
'allowSecond': '=',
'secondItem': '=',
'secondItemKey': '=',
'secondItemName': '@',
'secondOptionList': '=',
'actionTrigger': '=',
'firstItemTitle': '@',
'secondItemTitle': '@',
'defaultMsg': '@',
'icon': '@',
'isOpen': '=',
'dropdownAfterElementId': '@',
'leftIcon': '@',
},
link: function (scope, elem, attrs, ctrls) {
scope.isOpen = false;
if (attrs.mandatoryData !== undefined) mandatoryData = (attrs.mandatoryData === 'true' || attrs.mandatoryData === '');
//load invariant translations
scope.acceptMsg = Translator.getTranslation('apply_text');
scope.closeMsg = Translator.getTranslation('cancel_text');
var close = $(elem[0]).find('.js-cancel-button');
var save = $(elem[0]).find('.js-save-button');
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-dropdown-container');
var returnbutton = $(elem[0]).find('.js-return');
if (scope.dropdownAfterElementId !== undefined) {
container = container.insertAfter($("#" + scope.dropdownAfterElementId));
}
$(document).mouseup(function (e) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
if (!container.hasClass('hidden')) {
e.preventDefault();
close.trigger('click');
}
}
});
$(document).ready(function (e) {
// Safari 3.0+ "[object HTMLElementConstructor]"
var isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || (typeof safari !== 'undefined' && safari.pushNotification));
save.click(function (e) {
container.addClass('hidden');
$("#modalcontent").removeClass("modal-responsive");
if (isSafari == true) {
$(".base-selector__footer-mobile").removeClass("base-selector__footer-mobile--safari");
}
$("html").removeClass("fix-footer");
$("html").removeClass("fix-footer__html");
$("body").removeClass("fix-footer__body");
scope.isOpen = false;
shApi.fullWindow(false);
});
close.click(function (e) {
container.addClass('hidden');
$("#modalcontent").removeClass("modal-responsive");
if (isSafari == true) {
$(".base-selector__footer-mobile").removeClass("base-selector__footer-mobile--safari");
}
$("html").removeClass("fix-footer");
$("html").removeClass("fix-footer__html");
$("body").removeClass("fix-footer__body");
scope.isOpen = false;
shApi.fullWindow(false);
//callback execution
scope.onCancel();
});
button.click(function (e) {
if (container.hasClass('hidden')) {
container.removeClass('hidden');
$("#modalcontent").addClass("modal-responsive");
$("html").addClass("fix-footer");
$("html").addClass("fix-footer__html");
$("body").addClass("fix-footer__body");
if (isSafari == true) {
$(".base-selector__footer-mobile").addClass("base-selector__footer-mobile--safari");
}
scope.$apply(function () {
scope.isOpen = true;
});
shApi.fullWindow(true);
//init default:
scope.initialValues();
} else {
//e.preventDefault();
close.trigger('click');
}
});
returnbutton.click(function (e) {
close.trigger('click');
});
})
},
controller: function ($scope) {
//init when open
$scope.initialValues = function () {
$scope.isOpen = true;
if ($scope.allowSecond) {
if ($scope.secondItem != undefined && $scope.secondItem != null)
$scope.lastSecondSelectedKeyValue = $scope.secondItem[$scope.secondItemKey];
}
//Initialize first list
if ($scope.mainOptionList != undefined && $scope.mainOptionList != null) {
var finded = null;
if ($scope.mainItem != undefined && $scope.mainItem != null) {
finded = $.grep($scope.mainOptionList, function (e) { if (e[$scope.mainItemKey] === $scope.mainItem[$scope.mainItemKey]) return e; });
}
if (finded != null && finded.length > 0) {
$scope.mainItemSelected = finded[0];
$scope.$apply();
}
else if (mandatoryData) {
$scope.mainItemSelected = $scope.mainOptionList[0];
$scope.$apply();
}
}
}
$scope.$watch('mainItemSelected', function (newVal, oldVal) {
if (newVal !== oldVal) {
if ($scope.allowSecond && $scope.actionTrigger != undefined && newVal != undefined
&& newVal != null) {
$scope.actionTrigger = 'loadSecondaryValues:' + newVal[$scope.mainItemKey];
}
}
});
$scope.$watch('secondItemSelected', function (newVal, oldVal) {
if (newVal !== oldVal) {
if (newVal != undefined && newVal != null) {
$scope.lastSecondSelectedKeyValue = newVal[$scope.secondItemKey];
}
else
$scope.lastSecondSelectedKeyValue = null;
}
});
$scope.$watch('secondOptionList', function (newValues, oldValues) {
if (newValues != oldValues) {
if ($scope.allowSecond) {
$scope.secondItemSelected = undefined;
if ($scope.secondOptionList != undefined && $scope.secondOptionList != null) {
var finded = null;
if ($scope.lastSecondSelectedKeyValue != null) {
finded = $.grep($scope.secondOptionList, function (e) { if (e[$scope.secondItemKey] === $scope.lastSecondSelectedKeyValue) return e; });
}
if (finded != null && finded.length > 0)
$scope.secondItemSelected = finded[0];
else if (mandatoryData)
$scope.secondItemSelected = $scope.secondOptionList[0];
}
}
}
}, true);
$scope.checkDisabled = function () {
if (($scope.mainItemSelected == undefined || $scope.mainItemSelected == null)
|| ($scope.allowSecond && ($scope.secondItemSelected == undefined || $scope.secondItemSelected == null)))
return true;
return false;
};
$scope.onCancel = function () {
//if ($scope.actionTrigger != undefined) $scope.actionTrigger = 'apply';
//clear internal values
closeAndClearInternalValues();
};
$scope.onSave = function () {
$scope.mainItem = $scope.mainItemSelected;
if ($scope.allowSecond) $scope.secondItem = $scope.secondItemSelected;
if ($scope.actionTrigger != undefined) $scope.actionTrigger = 'apply';
closeAndClearInternalValues();
};
function closeAndClearInternalValues() {
$scope.mainItemSelected = $scope.secondItemSelected = undefined;
$scope.initialMainValue = $scope.initialSecondValue = undefined;
$scope.lastSecondSelectedKeyValue = null;
$scope.secondOptionList = undefined;
$scope.isOpen = false;
};
},
templateUrl: '/Scripts/app/Modules/stDoubleSelectorTemplate.html'
}
});
ngSharedDirectives.directive('stBaggageSelector', function (Translator, shApi) {
return {
restrict: 'E',
scope: {
'totalpackages': '=',
'mediumsuitcase': '=',
'specialbaggage': '=',
'blocksuitcasegroup': '=',
'blockspecificgroup': '=',
'blockmediumsuitcase': '=',
'blocklargesuitcase': '=',
'alternativeoption': '=',
'intromsg': '@',
'specialbaggagedescription': '=',
'suitcaserulemsg': '@',
'specificrulemsg': '@',
'defaultbaggage': '=',
'uptomsg': '@',
'inputmsg': '@',
'mainClass': '@',
'showLabel': '=',
'showIcon': '=',
'closemsg': '@',
'isOpen': '=',
'infomsg': '@',
'titlemsg': '@',
'mediumBaggage': '@',
'mediumBaggageInfo': '@',
'allowrestablish': '=',
'defaulttotalpackages': '=',
'defaultmediumsuitcase': '=',
'unselectmsg': '@',
},
link: function (scope, elem, attrs, ctrls) {
scope.isOpen = false;
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-dropdown-container');
var close = $(elem[0]).find('.js-save-button');
var returnbutton = $(elem[0]).find('.js-return');
$(document).mouseup(function (e) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
if (!container.hasClass('hidden')) {
e.preventDefault();
close.trigger('click');
}
}
});
$(document).ready(function (e) {
close.click(function () {
container.addClass('hidden');
scope.isOpen = false;
shApi.fullWindow(false);
});
button.click(function () {
if (container.hasClass('hidden')) {
container.removeClass('hidden');
scope.initialValues();
scope.$apply(function () {
scope.isOpen = true;
});
shApi.fullWindow(true);
}
else {
close.trigger('click');
}
});
returnbutton.click(function (e) {
scope.return();
close.trigger('click');
});
})
},
controller: function ($scope) {
$scope.addBaggage = function (mediumsuitcase) {
if (mediumsuitcase != 0) {
$scope.mediumsuitcase += mediumsuitcase;
$scope.totalpackages += mediumsuitcase;
}
//Cambia el por defecto
if ($scope.defaultbaggage != undefined)
$scope.defaultbaggage = false;
}
$scope.getTranslation = function (str) {
return Translator.getTranslation(str);
}
$scope.initialValues = function () {
$scope.inittotalpackages = $scope.totalpackages;
$scope.initmediumsuitcase = $scope.mediumsuitcase;
}
$scope.return = function () {
$scope.totalpackages = $scope.inittotalpackages;
$scope.mediumsuitcase = $scope.initmediumsuitcase;
}
$scope.restablish = function () {
if ($scope.allowrestablish) {
$scope.totalpackages = $scope.defaulttotalpackages;
$scope.mediumsuitcase = $scope.defaultmediumsuitcase;
}
}
},
templateUrl: '/Scripts/app/Modules/stBaggageSelectorTemplate.html'
}
}
);
ngSharedDirectives.directive('stRangeSelector', function (shApi) {
return {
restrict: 'E',
scope: {
'inputmsg': '@',
'callbackOnClose': '=',
'minvalue': '=',
'maxvalue': '=',
'stepnum': '=',
'range': '=',
'submsg': '@',
'closemsg': '@',
'units': '@',
'mainClass': '@',
'isOpen': '=',
'disabled': '=',
},
link: function (scope, elem, attrs, ctrls) {
scope.isOpen = false;
if (scope.disabled === undefined) scope.disabled = false;
var close = $(elem[0]).find('.js-save-button');
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-dropdown-container');
$(document).mouseup(function (e) {
if (!scope.fixed) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
if (!container.hasClass('hidden')) {
e.preventDefault();
close.trigger('click');
}
}
}
});
$(document).ready(function (e) {
close.click(function (e) {
container.addClass('hidden');
scope.isOpen = false;
shApi.fullWindow(false);
//callback execution to notify the directives that contain this directive
if (scope.callbackOnClose != undefined && scope.checkForChanges())
scope.callbackOnClose();
});
button.click(function (e) {
if (container.hasClass('hidden')) {
if (!scope.disabled) {
container.removeClass('hidden');
scope.$apply(function () {
scope.isOpen = true;
});
shApi.fullWindow(true);
scope.initialValues();
}
} else {
//e.preventDefault();
close.trigger('click');
}
})
})
},
controller: function ($scope) {
$scope.initialValues = function () {
$scope.minInitial = $scope.range[0];
$scope.maxInitial = $scope.range[1];
}
$scope.checkForChanges = function () {
var changes = false;
if ($scope.minInitial !== $scope.range[0] || $scope.maxInitial !== $scope.range[1]) changes = true;
return changes;
}
},
templateUrl: '/Scripts/app/Modules/stRangeSelectorTemplate.html'
}
});
ngSharedDirectives.directive('inputFocused', function ($timeout, $document) {
return {
scope: { trigger: '@inputFocused' },
link: function (scope, element) {
scope.$watch('trigger', function (value) {
if (value.substr(0, 4) === "true") {
$timeout(function () {
element[0].focus();
element[0].blur();
});
}
});
}
};
});
ngSharedDirectives.directive('stMultiselectDropdown', function ($filter, shApi) {
return {
restrict: 'E',
scope: {
model: '=',
selectedmsg: '@',
options: '=',
titlemsg: '@',
defaultmsg: '@',
unselectmsg: '@',
closemsg: '@',
name: '@',
topBoolName: '@',
callbackOnClose: '=',
id: '@',
multiselectClass: '@',
controlName: '@',
isOpen: '=',
disabled: '=',
mainClass: '@',
bookserviceprovider: '@',
bookserviceproviderselected: '@',
showtags: '=',
filteralone: '=',
isclosed: '=',
filled: '@',
},
templateUrl: '/Scripts/app/Modules/stMultiselectDropdown.html',
link: function (scope, elem, attrs, ctrls) {
if (scope.fixed === undefined) scope.fixed = false;
if (scope.disabled === undefined) scope.disabled = false;
scope.hasIcon = false;
scope.isOpen = false;
scope.hasTopOptions = false;
if (attrs.iconClass !== undefined) { scope.hasIcon = true; scope.iconClass = attrs.iconClass; }
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-dropdown-container');
var close = $(elem[0]).find('.js-save-button');
var returnbutton = $(elem[0]).find('.js-return');
if (scope.filteralone == undefined || scope.filteralone == false) {
$(document).mouseup(function (e) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
if (!container.hasClass('hidden')) {
e.preventDefault();
close.trigger('click');
}
}
});
$(document).ready(function (e) {
close.click(function (e) {
container.addClass('hidden');
scope.isOpen = false;
shApi.fullWindow(false);
if (scope.callbackOnClose != undefined)
scope.callbackOnClose();
});
button.click(function () {
if (container.hasClass('hidden')) {
if (!scope.disabled) {
container.removeClass('hidden');
scope.initialValues();
scope.$apply(function () {
scope.isOpen = true;
});
shApi.fullWindow(true);
}
} else {
container.addClass('hidden');
close.trigger('click');
}
});
returnbutton.click(function (e) {
scope.return();
close.trigger('click');
});
scope.init();
})
} else {
$(document).ready(function (e) {
scope.init();
})
}
},
controller: function ($scope) {
$scope.init = function () {
if ($scope.model == undefined) $scope.model = [];
else loadInternalValues($scope.model);
}
//open
$scope.initialValues = function () {
$scope.initialList = angular.copy($scope.model);
}
//only mobile
$scope.return = function () {
$scope.model = angular.copy($scope.initialList);
}
//Default use as dictionary
$scope.getName = function (option) {
if (typeof $scope.name == 'undefined' || $scope.name == null)
return option["value"];
else
return option[$scope.name];
}
$scope.getValue = function (option) {
if (typeof $scope.id == 'undefined' || $scope.id == null)
return option["key"];
else
return option[$scope.id];
}
$scope.getIsTopOption = function (option) {
var isTopOption = false;
if (typeof $scope.topBoolName != 'undefined' && $scope.topBoolName != null)
isTopOption = option[$scope.topBoolName];
$scope.hasTopOptions |= isTopOption;
return isTopOption;
}
$scope.getIsFilled = function (option) {
if (typeof $scope.filled == 'undefined' || $scope.filled == null)
return option["filled"];
else
return option[$scope.filled];
}
$scope.resumeName = $scope.defaultmsg;
$scope.selectAll = function () {
$scope.model = [];
angular.forEach($scope.options, function (item, index) {
$scope.model.push(item);
});
};
$scope.deselectAll = function () {
$scope.model = [];
};
$scope.toggleSelectItem = function (option) {
var intIndex = -1;
for (var idx in $scope.model) {
if ($scope.getValue(option) == $scope.getValue($scope.model[idx])) {
intIndex = idx;
break;
}
};
if (intIndex >= 0) {
$scope.model.splice(intIndex, 1);
} else {
$scope.model.push(option);
}
};
$scope.getChecked = function (option) {
var varSelected = '';
for (var idx in $scope.model) {
if ($scope.getValue(option) == $scope.getValue($scope.model[idx])) {
varSelected = true;
break;
}
}
return (varSelected);
};
$scope.$watchCollection('model', function (newValue, oldValue) {
if (newValue != undefined && newValue != null) {
loadInternalValues(newValue);
}
});
function loadInternalValues(newValue) {
if ($scope.filteralone != true) {
if (newValue.length > 0) {
if (newValue.length == $scope.options.length) {
$scope.resumeName = $scope.defaultmsg;
}
else {
if ($scope.selectedmsg != undefined && $scope.selectedmsg != null) {
$scope.resumeName = $filter('replace')($scope.selectedmsg, newValue.length);
}
else {
$scope.resumeName = newValue.length;
}
}
}
else {
$scope.resumeName = $scope.defaultmsg;
}
}
}
$scope.showHideDropdown = function () {
$scope.isclosed = !$scope.isclosed;
}
$scope.callApplyTransferFilters = function () {
if ($scope.$parent.callApply == false) {
$scope.$parent.callApply = true;
} else {
$scope.$parent.callApply = false;
}
}
}
}
});
ngSharedDirectives.directive('stSearcherByText', function ($filter, shApi) {
return {
restrict: 'E',
scope: {
model: '=',
unselectmsg: '@',
closemsg: '@',
defaultmsg: '@',
isOpen: '=',
callbackOnClose: '=',
disabled: '=',
mainClass: '@'
},
templateUrl: '/Scripts/app/Modules/stSearcherByText.html',
link: function (scope, elem, attrs, ctrls) {
scope.isOpen = false;
if (scope.fixed === undefined) scope.fixed = false;
if (scope.disabled === undefined) scope.disabled = false;
scope.hasIcon = false;
if (attrs.iconClass !== undefined) { scope.hasIcon = true; scope.iconClass = attrs.iconClass; }
scope.initValueOpen();
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-dropdown-container');
var close = $(elem[0]).find('.js-save-button');
var returnbutton = $(elem[0]).find('.js-return');
$(document).mouseup(function (e) {
if (!scope.fixed) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
if (!container.hasClass('hidden')) {
e.preventDefault();
close.trigger('click');
}
}
}
});
$(document).ready(function (e) {
close.click(function (e) {
scope.closeClick();
});
button.click(function () {
if (container.hasClass('hidden')) {
if (!scope.disabled) {
scope.initValueOpen();
container.removeClass('hidden');
container.find("input").first().focus();
scope.$apply(function () {
scope.isOpen = true;
});
shApi.fullWindow(true);
}
} else {
container.addClass('hidden');
close.trigger('click');
}
})
returnbutton.click(function (e) {
scope.return();
close.trigger('click');
});
});
scope.closeClick = function () {
container.addClass('hidden');
scope.isOpen = false;
shApi.fullWindow(false);
if (scope.callbackOnClose != undefined && scope.checkForChanges())
scope.callbackOnClose();
};
},
controller: function ($scope) {
$scope.initValueOpen = function () {
$scope.initialValue = $scope.model;
}
$scope.return = function () {
$scope.model = $scope.initialValue;
}
$scope.checkForChanges = function () {
var changes = false;
if ($scope.initialValue !== $scope.model) changes = true;
return changes;
}
$scope.$watchCollection('model', function (newValue, oldValue) {
$scope.resumeName = $scope.defaultmsg;
if (newValue != undefined && newValue != null) {
if (newValue.length > 0) {
$scope.resumeName = newValue;
}
}
});
$scope.deselectAll = function () {
$scope.model = null;
};
}
}
});
ngSharedDirectives.directive('stMultiselectPickup', function ($timeout, Purchases, shApi) {
return {
restrict: 'AE',
scope: {
displayAttr: '@',
mainClass: '@',
inputClass: '@',
selectedItems: '=',
allItems: '=',
readOnly: '=',
addItem: '&',
culture: '=',
pickupplaceholdermsg: '@',
pickupsearchmsg: '@',
removeItem: '&',
titlemsg: '@',
},
link: function (scope, elem, attrs) {
var button = $(elem[0]).find('.js-button-selector');
var container = $(elem[0]).find('.js-container');
var returnbutton = $(elem[0]).find('.js-return');
$(document).mouseup(function (e) {
if (!container.is(e.target) && container.has(e.target).length === 0
&& !button.is(e.target) && button.has(e.target).length === 0) {
//only trigger event on close if the container was active, then, hidden it
if (!container.hasClass('hidden')) {
e.preventDefault();
closeSelector();
}
}
});
$(document).ready(function (e) {
button.click(function () {
if (container.hasClass('hidden')) {
container.removeClass('hidden');
shApi.fullWindow(true);
} else {
closeSelector();
}
});
returnbutton.click(function (e) {
closeSelector();
});
});
scope.updateSelectedItems = function (obj) {
var selectedObj;
for (i = 0; typeof scope.selectedItems !== 'undefined' && i < scope.selectedItems.length; i++) {
if (scope.selectedItems[i][scope.displayAttr].toUpperCase() === obj[scope.displayAttr].toUpperCase()) {
selectedObj = scope.selectedItems[i];
break;
}
}
if (typeof selectedObj === 'undefined') {
scope.addItem({ item: obj });
} else {
scope.removeItem({ item: selectedObj });
}
closeSelector();
}
scope.isItemSelected = function (item) {
if (typeof scope.selectedItems === 'undefined') return false;
var tmpItem;
for (i = 0; i < scope.selectedItems.length; i++) {
tmpItem = scope.selectedItems[i];
if (typeof tmpItem !== 'undefined'
&& typeof tmpItem[scope.displayAttr] !== 'undefined'
&& typeof item[scope.displayAttr] !== 'undefined'
&& tmpItem[scope.displayAttr].toUpperCase() === item[scope.displayAttr].toUpperCase()) {
return true;
}
}
return false;
}
scope.commaDelimitedSelected = function () {
var list = "";
angular.forEach(scope.selectedItems, function (item, index) {
list += item[scope.displayAttr];
if (index < scope.selectedItems.length - 1) list += ', ';
});
return list.length ? list : scope.pickupplaceholdermsg;
}
function closeSelector() {
container.addClass('hidden');
shApi.fullWindow(false);
}
},
templateUrl: '/Scripts/app/Modules/stMultiselectPickup.html'
}
});
ngSharedDirectives.directive('customTagsinput', function ($timeout, shApi) {
var tagsAfter = false;//by default tags appear before the input element (as in the checked examples)
var maxTags = 0;
//$timeout(function () { console.log('dd'); }, 2000);
return {
restrict: 'EA',
scope: {
inputTagText: '@', inputTagId: '@', inputTagDescription: '@', tagsInputArray: '=', placeHolderContent: '@', typeaheadTooltip: '@', typeaheadCall: "=", typeaheadLabel: '@', maxTags: "=", changesTrigger: '=',
searchTemplate: '@', selectCallback: '=', filters: '='
},
link: function (scope, element, attrs) {
scope.searchDone = false;
$('.tagscontainer').click(function () {
$(this).find('input[type="text"]').focus();
});
//set configuation attrs
//bool tagsAfter to set the position of input elements with regards to tags collection
if (attrs.tagsAfter !== undefined) tagsAfter = (attrs.tagsAfter === 'true' || attrs.tagsAfter === '');
scope.iconClass = attrs.iconClass !== undefined ? attrs.iconClass : 'st-search fa-fw font-up-1';
scope.inputId = attrs.inputId !== undefined ? attrs.inputId : 'tags';
if (scope.filters === undefined) scope.filters = false;
//draws the new tag element where corresponds to configuration above
scope.drawInputTag = function (object) {
//we save the id of the object in the name to have an identification of the object in order to remove it, we do it this way to not rely on text just in case in the future
//we have two texts that are the same but we also have a different description(could be a tooltip)
var htmlSpan = '
' + object[scope.inputTagText]
+ ' ';
if (tagsAfter) $(element).find(".div-search-input").append(htmlSpan);
else $(element).find(".content-tags").append(htmlSpan);
//attaching handler when on click event is fired in a
$(element).find("a[name='" + object[scope.inputTagId] + "']").click(function (event) {
var controlToFocus = $($(this).closest('.text-addon')).find('.controlToFocus')[0];
var id = $(this)[0].name;
scope.removeItem(id);
$(this).parent().parent().remove();//remove text tag
if (scope.filters) {
$('#search-text-tag').val("");
}
var aElement = $(this);
$timeout(function () {
if (controlToFocus) {
$(controlToFocus).focus();
}
});
});
}
scope.clearUnavailableTags = function (newVal, oldVal) {
if (newVal == undefined || newVal === null || newVal.length == 0) {
$(element).find(".tag").remove();
}
else if (newVal != undefined && newVal != null && newVal.length > 0) {
var tagKeys = [];
$.each(newVal, function (idx, item) {
tagKeys.push(item[scope.inputTagId]);
});
var existingTags = $(element).find(".content-tags .tag .removeDiv a");
$.each(existingTags, function (idx, item) {
if (!shApi.checkIfContains(tagKeys, item.name)) {
$(element).find("a[name='" + item.name + "']").parent().parent().remove();
}
});
}
}
scope.readOnly = function (val) {
if (val) {
$(element).find("input").attr("disabled", true);
scope.searchDone = true;
}
else {
$(element).find("input").removeAttr("disabled");
scope.searchDone = false;
}
$(element).find("input").attr("placeholder", attrs.placeHolderContent);
}
scope.addTagFromModel = function (object) {
//Clear input
$(element).find("input").val('');
//Si no existe ya un elemento en la lista
var elem = $(element).find("a[name='" + object[scope.inputTagId] + "']");
if (elem.length === 0) scope.drawInputTag(object);
}
scope.init();
},
controller: function ($scope) {
$scope.selectedObject = "";
//vbles initializations
$scope.init = function () {
if ($scope.tagsInputArray === undefined) $scope.tagsInputArray = [];
else loadInternalValues($scope.tagsInputArray);
//end initializations
}
//typeahead method
$scope.getArrayData = function (filter) {
return $scope.typeaheadCall($scope.selectedObject);
}
//add new item
$scope.newSelectedItem = function () {
//check if the object exists
var obj = $.grep($scope.tagsInputArray, function (e) { return e[$scope.inputTagId] == $scope.selectedObject[$scope.inputTagId]; });
if (obj.length == 0) {
$scope.tagsInputArray.push($scope.selectedObject);
$scope.drawInputTag($scope.selectedObject);
}
$scope.checkMaxTags();
//clean input
$scope.resetSelectedObject();
if ($scope.selectCallback != undefined)
$scope.selectCallback();
}
$scope.removeItem = function (id) {
var index = -1;
$.each($scope.tagsInputArray, function (idx, item) { if (item[$scope.inputTagId] == id) { index = idx; return false; } });
if (index > -1) $scope.tagsInputArray.splice(index, 1);
$scope.checkMaxTags();
}
$scope.checkMaxTags = function () {
if ($scope.tagsInputArray != undefined && $scope.tagsInputArray != null) {
if ($scope.tagsInputArray.length >= $scope.maxTags) {
$scope.readOnly(true);
}
else {
$scope.readOnly(false);
}
}
}
//clean input after adding
$scope.resetSelectedObject = function () {
$scope.selectedObject = "";
//var obj = document.getElementById(activitieSearcher);
//obj.removeClass('open-mobile');
$('.div-input-v2').removeClass('open-mobile');
}
//if language filters is reset from outside controller or service... directive has to reset the DOM
$scope.$watch('tagsInputArray', function (newVal, oldVal) {
$scope.changesTrigger = "tagsChange";
loadInternalValues(newVal);
}, true);
function loadInternalValues(newVal, oldVal) {
$scope.checkMaxTags();
//clean dom tags..
$scope.clearUnavailableTags(newVal, oldVal);
//If the value is reset outside controller
if (newVal != undefined && newVal != null && newVal.length > 0) {
$.each(newVal, function (idx, elem) {
$scope.addTagFromModel(newVal[idx]);
});
}
}
},
templateUrl: "/Scripts/app/Modules/tagsInputTemplate.html"
};
});
ngSharedDirectives.filter('startFrom', function () {
return function (input, start) {
start = +start; //parse to int
return input.slice(start);
}
});
ngSharedDirectives.directive('popoverElem', function () {
return {
link: function (scope, element, attrs) {
element.on('click', function () {
element.addClass('trigger');
});
}
}
});
ngSharedDirectives.directive('popoverClose', function ($timeout) {
return {
scope: {
excludeClass: '@'
},
link: function (scope, element, attrs) {
var trigger = document.getElementsByClassName('trigger');
function closeTrigger(i) {
$timeout(function () {
angular.element(trigger[0]).click();
});
}
element.on('click', function (event) {
var etarget = angular.element(event.target);
var tlength = trigger.length;
if (!etarget.hasClass('trigger') && !etarget.hasClass(scope.excludeClass)) {
for (var i = 0; i < tlength; i++) {
closeTrigger(i);
}
}
});
}
};
});
//Directiva para que funcionen los popovers en un ngRepeat
ngSharedDirectives.directive('bsPopover', function () {
return function (scope, element, attrs) {
element.find("a[rel=popover]").popover({ placement: 'right', html: 'true' });
$('body').on('click', function (e) {
$('a[rel="popover"]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('hide');
}
});
});
};
});
ngSharedDirectives.directive('focusOnElementChange', function ($timeout) {
return {
scope: {
containerToWatch: '=',
elementToFocus: '@',
},
link: function (scope, element, attrs) {
// Focus en el primer control con la clase .controlToFocus en el elemento
scope.$watch('containerToWatch', function (newValue, oldValue) {
if (newValue != oldValue) {
$timeout(function () {
var tab = $($('.' + newValue)[0]);
if (tab) {
var first = tab.find(scope.elementToFocus)[0];
if (first) {
first.focus();
}
}
});
}
});
}
}
});
/*2 decimal places*/
ngSharedDirectives.directive('decimalPlaces', function () {
return {
link: function (scope, ele, attrs) {
ele.bind('keyup keypress', function (e) {
var newVal = $(this).val() + (e.charCode !== 0 ? String.fromCharCode(e.charCode) : '');
if ($(this).val().search(/(.*)\.[0-9][0-9]/) === 0 && newVal.length > $(this).val().length) {
e.preventDefault();
}
});
}
};
});
ngSharedDirectives.directive('focusClass', function () {
return {
restrict: 'A',
priority: 1,
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
var parentClass = null;
if (attrs.focusClassname !== undefined)
parentClass = attrs.focusClassname;
else
parentClass = "div-input-v2"; //default parent class
var parents = element.parents('.' + parentClass);
var parent = parents.first();
if (parent != undefined && parent != null) {
element.bind('focus', function () {
parent.addClass('focus');
}).bind('blur', function () {
parent.removeClass('focus');
});
}
}
};
});
ngSharedDirectives.directive('stAutocomplete', function ($timeout, shApi) {
return {
restrict: 'E',
require: ['^form'],
scope: {
'extraClasses': '@',
'iconClass': '@',
'tamt': '@',
'typeaheadTemplate': '@',
'headerTitle': '@',
'inputId': '@',
'inputName': '@',
'textProperty': '@',
'autocomplete': '=',
'noResultsControl': '=',
'disabled': '=',
'arrayTranslations': '=',
'placeholder': '@',
'fromlistErrorMsg': '@',
'requiredErrorMsg': '@',
'pointErrorMsg': '@',
'tooltipError': '@',
'functionData': '=',
'required': '=',
'classInput': '@',
'clearTags': '=',
'hideOldx': '=',
'showNewx': '=',
'onlyRigth': '=',
'otherInput': '=',
'clearsearchtext': '@',
'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();
}
});
}
};
});
}
)();
(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 = $("
");
var start = $("
");
var end = $("
");
container.append(selectfield).append(start).append(end);
var inputs = $("input", container);
inputs.css({
"padding": "4px",
"width": "50%",
"box-sizing": "border-box",
})
.val(cell.getValue());
function buildDateString() {
var json = { type:selectfield.val(), start: start.val(), end: end.val() };
return JSON.stringify(json);
}
function buildTypeString() {
var json = { type:selectfield.val()};
return JSON.stringify(json);
}
selectfield.change(function() {
var selectvalue = selectfield.val();
if (selectvalue != "beetween_reservations") {
start.val("");
end.val("");
start.hide();
end.hide();
success(buildTypeString());
} else {
start.show();
end.show();
}
});
//submit new value on blur
inputs.on("change blur",
function(e) {
success(buildDateString());
});
//submit new value on enter
inputs.on("keydown",
function(e) {
if (e.keyCode == 13) {
success(buildDateString());
}
if (e.keyCode == 27) {
cancel();
}
});
return container;
};
//custom filter function
this.dateFilterFunction=function(headerValue, rowValue, rowData, filterParams){
//headerValue - the value of the header filter element
//rowValue - the value of the column in this row
//rowData - the data for the row being filtered
//filterParams - params object passed to the headerFilterFuncParams property
var format = filterParams.format || "DD/MM/YYYY";
var start = moment(headerValue.start);
var end = moment(headerValue.end);
var value = moment(rowValue, format)
if(rowValue){
if(start.isValid()){
if(end.isValid()){
return value >= start && value <= end;
}else{
return value >= start;
}
}else{
if(end.isValid()){
return value <= end;
}
}
}
return false; //must return a boolean, true if it passes the filter.
} }]);
})();
(function () {
'use strict';
var ngValidationsService = angular.module('ngValidationsService', ['ngResource']);
ngValidationsService.service('Validations', ['$resource', function ($resource) {
this.existsUserEmail = function (email, prefix) {
return $resource(prefix + '/webapi/registrationvalidation/email/:mail', { mail: email },
{
get: { method: 'GET', transformResponse: transformGetToBoolean },
}).get().$promise;
};
this.existsPartnerEmail = function (email, prefix) {
return $resource(prefix + '/webapi/registrationpartnervalidation/email/:mail', { mail: email },
{
get: { method: 'GET', transformResponse: transformGetToBoolean },
}).get().$promise;
};
this.existsClientEmail = function (email, prefix) {
if (email == undefined || email.length == 0)
return;
return $resource(prefix + '/webapi/clientregistrationvalidation/email/:mail/', { mail: email },
{
get: { method: 'GET', transformResponse: transformGetToBoolean },
}).get().$promise;
};
this.existsCompanyVat = function (vatnumber, prefix) {
return $resource(prefix + '/webapi/registrationvalidation/vatnumber/:vatnumber', { vatnumber: vatnumber },
{
get: { method: 'GET', transformResponse: transformGetToBoolean },
}).get().$promise;
};
this.existsInternalUserEmail = function (email, prefix) {
return $resource(prefix + '/webapi/internaluserregistrationvalidation/email/:mail', { mail: email },
{
get: { method: 'GET', transformResponse: transformGetToBoolean },
}).get().$promise;
};
this.existsUserEmailInternalDashboard = function (email, prefix) {
return $resource(prefix + '/webapi/registerprofessionalvalidation/email/:mail', { mail: email },
{
get: { method: 'GET', transformResponse: transformGetToBoolean },
}).get().$promise;
};
this.existsDiscountCode = function (code, prefix) {
return $resource(prefix + '/webapi/internaldiscountvalidation/discountCode/:discountCode', { discountCode: code },
{
get: { method: 'GET', transformResponse: transformGetToBoolean },
}).get().$promise;
};
}]);
function transformGetToBoolean(json, headerGetter) {
var fromJson = angular.fromJson({ raw: (json === "true") });
return fromJson;
}
})();
/**!
* AngularJS file upload directives and services. Supports: file upload/drop/paste, resume, cancel/abort,
* progress, resize, thumbnail, preview, validation and CORS
* FileAPI Flash shim for old browsers not supporting FormData
* @author Danial
* @version 12.2.13
*/
(function () {
/** @namespace FileAPI.noContentTimeout */
function patchXHR(fnName, newFn) {
window.XMLHttpRequest.prototype[fnName] = newFn(window.XMLHttpRequest.prototype[fnName]);
}
function redefineProp(xhr, prop, fn) {
try {
Object.defineProperty(xhr, prop, { get: fn });
} catch (e) {/*ignore*/
}
}
if (!window.FileAPI) {
window.FileAPI = {};
}
if (!window.XMLHttpRequest) {
throw 'AJAX is not supported. XMLHttpRequest is not defined.';
}
FileAPI.shouldLoad = !window.FormData || FileAPI.forceLoad;
if (FileAPI.shouldLoad) {
var initializeUploadListener = function (xhr) {
if (!xhr.__listeners) {
if (!xhr.upload) xhr.upload = {};
xhr.__listeners = [];
var origAddEventListener = xhr.upload.addEventListener;
xhr.upload.addEventListener = function (t, fn) {
xhr.__listeners[t] = fn;
if (origAddEventListener) origAddEventListener.apply(this, arguments);
};
}
};
patchXHR('open', function (orig) {
return function (m, url, b) {
initializeUploadListener(this);
this.__url = url;
try {
orig.apply(this, [m, url, b]);
} catch (e) {
if (e.message.indexOf('Access is denied') > -1) {
this.__origError = e;
orig.apply(this, [m, '_fix_for_ie_crossdomain__', b]);
}
}
};
});
patchXHR('getResponseHeader', function (orig) {
return function (h) {
return this.__fileApiXHR && this.__fileApiXHR.getResponseHeader ? this.__fileApiXHR.getResponseHeader(h) : (orig == null ? null : orig.apply(this, [h]));
};
});
patchXHR('getAllResponseHeaders', function (orig) {
return function () {
return this.__fileApiXHR && this.__fileApiXHR.getAllResponseHeaders ? this.__fileApiXHR.getAllResponseHeaders() : (orig == null ? null : orig.apply(this));
};
});
patchXHR('abort', function (orig) {
return function () {
return this.__fileApiXHR && this.__fileApiXHR.abort ? this.__fileApiXHR.abort() : (orig == null ? null : orig.apply(this));
};
});
patchXHR('setRequestHeader', function (orig) {
return function (header, value) {
if (header === '__setXHR_') {
initializeUploadListener(this);
var val = value(this);
// fix for angular < 1.2.0
if (val instanceof Function) {
val(this);
}
} else {
this.__requestHeaders = this.__requestHeaders || {};
this.__requestHeaders[header] = value;
orig.apply(this, arguments);
}
};
});
patchXHR('send', function (orig) {
return function () {
var xhr = this;
if (arguments[0] && arguments[0].__isFileAPIShim) {
var formData = arguments[0];
var config = {
url: xhr.__url,
jsonp: false, //removes the callback form param
cache: true, //removes the ?fileapiXXX in the url
complete: function (err, fileApiXHR) {
if (err && angular.isString(err) && err.indexOf('#2174') !== -1) {
// this error seems to be fine the file is being uploaded properly.
err = null;
}
xhr.__completed = true;
if (!err && xhr.__listeners.load)
xhr.__listeners.load({
type: 'load',
loaded: xhr.__loaded,
total: xhr.__total,
target: xhr,
lengthComputable: true
});
if (!err && xhr.__listeners.loadend)
xhr.__listeners.loadend({
type: 'loadend',
loaded: xhr.__loaded,
total: xhr.__total,
target: xhr,
lengthComputable: true
});
if (err === 'abort' && xhr.__listeners.abort)
xhr.__listeners.abort({
type: 'abort',
loaded: xhr.__loaded,
total: xhr.__total,
target: xhr,
lengthComputable: true
});
if (fileApiXHR.status !== undefined) redefineProp(xhr, 'status', function () {
return (fileApiXHR.status === 0 && err && err !== 'abort') ? 500 : fileApiXHR.status;
});
if (fileApiXHR.statusText !== undefined) redefineProp(xhr, 'statusText', function () {
return fileApiXHR.statusText;
});
redefineProp(xhr, 'readyState', function () {
return 4;
});
if (fileApiXHR.response !== undefined) redefineProp(xhr, 'response', function () {
return fileApiXHR.response;
});
var resp = fileApiXHR.responseText || (err && fileApiXHR.status === 0 && err !== 'abort' ? err : undefined);
redefineProp(xhr, 'responseText', function () {
return resp;
});
redefineProp(xhr, 'response', function () {
return resp;
});
if (err) redefineProp(xhr, 'err', function () {
return err;
});
xhr.__fileApiXHR = fileApiXHR;
if (xhr.onreadystatechange) xhr.onreadystatechange();
if (xhr.onload) xhr.onload();
},
progress: function (e) {
e.target = xhr;
if (xhr.__listeners.progress) xhr.__listeners.progress(e);
xhr.__total = e.total;
xhr.__loaded = e.loaded;
if (e.total === e.loaded) {
// fix flash issue that doesn't call complete if there is no response text from the server
var _this = this;
setTimeout(function () {
if (!xhr.__completed) {
xhr.getAllResponseHeaders = function () {
};
_this.complete(null, { status: 204, statusText: 'No Content' });
}
}, FileAPI.noContentTimeout || 10000);
}
},
headers: xhr.__requestHeaders
};
config.data = {};
config.files = {};
for (var i = 0; i < formData.data.length; i++) {
var item = formData.data[i];
if (item.val != null && item.val.name != null && item.val.size != null && item.val.type != null) {
config.files[item.key] = item.val;
} else {
config.data[item.key] = item.val;
}
}
setTimeout(function () {
if (!FileAPI.hasFlash) {
throw 'Adode Flash Player need to be installed. To check ahead use "FileAPI.hasFlash"';
}
xhr.__fileApiXHR = FileAPI.upload(config);
}, 1);
} else {
if (this.__origError) {
throw this.__origError;
}
orig.apply(xhr, arguments);
}
};
});
window.XMLHttpRequest.__isFileAPIShim = true;
window.FormData = FormData = function () {
return {
append: function (key, val, name) {
if (val.__isFileAPIBlobShim) {
val = val.data[0];
}
this.data.push({
key: key,
val: val,
name: name
});
},
data: [],
__isFileAPIShim: true
};
};
window.Blob = Blob = function (b) {
return {
data: b,
__isFileAPIBlobShim: true
};
};
}
})();
(function () {
/** @namespace FileAPI.forceLoad */
/** @namespace window.FileAPI.jsUrl */
/** @namespace window.FileAPI.jsPath */
function isInputTypeFile(elem) {
return elem[0].tagName.toLowerCase() === 'input' && elem.attr('type') && elem.attr('type').toLowerCase() === 'file';
}
function hasFlash() {
try {
var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
if (fo) return true;
} catch (e) {
if (navigator.mimeTypes['application/x-shockwave-flash'] !== undefined) return true;
}
return false;
}
function getOffset(obj) {
var left = 0, top = 0;
if (window.jQuery) {
return jQuery(obj).offset();
}
if (obj.offsetParent) {
do {
left += (obj.offsetLeft - obj.scrollLeft);
top += (obj.offsetTop - obj.scrollTop);
obj = obj.offsetParent;
} while (obj);
}
return {
left: left,
top: top
};
}
if (FileAPI.shouldLoad) {
FileAPI.hasFlash = hasFlash();
//load FileAPI
if (FileAPI.forceLoad) {
FileAPI.html5 = false;
}
if (!FileAPI.upload) {
var jsUrl, basePath, script = document.createElement('script'), allScripts = document.getElementsByTagName('script'), i, index, src;
if (window.FileAPI.jsUrl) {
jsUrl = window.FileAPI.jsUrl;
} else if (window.FileAPI.jsPath) {
basePath = window.FileAPI.jsPath;
} else {
for (i = 0; i < allScripts.length; i++) {
src = allScripts[i].src;
index = src.search(/\/ng\-file\-upload[\-a-zA-z0-9\.]*\.js/);
if (index > -1) {
basePath = src.substring(0, index + 1);
break;
}
}
}
if (FileAPI.staticPath == null) FileAPI.staticPath = basePath;
script.setAttribute('src', jsUrl || basePath + 'FileAPI.min.js');
document.getElementsByTagName('head')[0].appendChild(script);
}
FileAPI.ngfFixIE = function (elem, fileElem, changeFn) {
if (!hasFlash()) {
throw 'Adode Flash Player need to be installed. To check ahead use "FileAPI.hasFlash"';
}
var fixInputStyle = function () {
var label = fileElem.parent();
if (elem.attr('disabled')) {
if (label) label.removeClass('js-fileapi-wrapper');
} else {
if (!fileElem.attr('__ngf_flash_')) {
fileElem.unbind('change');
fileElem.unbind('click');
fileElem.bind('change', function (evt) {
fileApiChangeFn.apply(this, [evt]);
changeFn.apply(this, [evt]);
});
fileElem.attr('__ngf_flash_', 'true');
}
label.addClass('js-fileapi-wrapper');
if (!isInputTypeFile(elem)) {
label.css('position', 'absolute')
.css('top', getOffset(elem[0]).top + 'px').css('left', getOffset(elem[0]).left + 'px')
.css('width', elem[0].offsetWidth + 'px').css('height', elem[0].offsetHeight + 'px')
.css('filter', 'alpha(opacity=0)').css('display', elem.css('display'))
.css('overflow', 'hidden').css('z-index', '900000')
.css('visibility', 'visible');
fileElem.css('width', elem[0].offsetWidth + 'px').css('height', elem[0].offsetHeight + 'px')
.css('position', 'absolute').css('top', '0px').css('left', '0px');
}
}
};
elem.bind('mouseenter', fixInputStyle);
var fileApiChangeFn = function (evt) {
var files = FileAPI.getFiles(evt);
//just a double check for #233
for (var i = 0; i < files.length; i++) {
if (files[i].size === undefined) files[i].size = 0;
if (files[i].name === undefined) files[i].name = 'file';
if (files[i].type === undefined) files[i].type = 'undefined';
}
if (!evt.target) {
evt.target = {};
}
evt.target.files = files;
// if evt.target.files is not writable use helper field
if (evt.target.files !== files) {
evt.__files_ = files;
}
(evt.__files_ || evt.target.files).item = function (i) {
return (evt.__files_ || evt.target.files)[i] || null;
};
};
};
FileAPI.disableFileInput = function (elem, disable) {
if (disable) {
elem.removeClass('js-fileapi-wrapper');
} else {
elem.addClass('js-fileapi-wrapper');
}
};
}
})();
if (!window.FileReader) {
window.FileReader = function () {
var _this = this, loadStarted = false;
this.listeners = {};
this.addEventListener = function (type, fn) {
_this.listeners[type] = _this.listeners[type] || [];
_this.listeners[type].push(fn);
};
this.removeEventListener = function (type, fn) {
if (_this.listeners[type]) _this.listeners[type].splice(_this.listeners[type].indexOf(fn), 1);
};
this.dispatchEvent = function (evt) {
var list = _this.listeners[evt.type];
if (list) {
for (var i = 0; i < list.length; i++) {
list[i].call(_this, evt);
}
}
};
this.onabort = this.onerror = this.onload = this.onloadstart = this.onloadend = this.onprogress = null;
var constructEvent = function (type, evt) {
var e = { type: type, target: _this, loaded: evt.loaded, total: evt.total, error: evt.error };
if (evt.result != null) e.target.result = evt.result;
return e;
};
var listener = function (evt) {
if (!loadStarted) {
loadStarted = true;
if (_this.onloadstart) _this.onloadstart(constructEvent('loadstart', evt));
}
var e;
if (evt.type === 'load') {
if (_this.onloadend) _this.onloadend(constructEvent('loadend', evt));
e = constructEvent('load', evt);
if (_this.onload) _this.onload(e);
_this.dispatchEvent(e);
} else if (evt.type === 'progress') {
e = constructEvent('progress', evt);
if (_this.onprogress) _this.onprogress(e);
_this.dispatchEvent(e);
} else {
e = constructEvent('error', evt);
if (_this.onerror) _this.onerror(e);
_this.dispatchEvent(e);
}
};
this.readAsDataURL = function (file) {
FileAPI.readAsDataURL(file, listener);
};
this.readAsText = function (file) {
FileAPI.readAsText(file, listener);
};
};
}
/**!
* AngularJS file upload directives and services. Supoorts: file upload/drop/paste, resume, cancel/abort,
* progress, resize, thumbnail, preview, validation and CORS
* @author Danial
* @version 12.2.13
*/
if (window.XMLHttpRequest && !(window.FileAPI && FileAPI.shouldLoad)) {
window.XMLHttpRequest.prototype.setRequestHeader = (function (orig) {
return function (header, value) {
if (header === '__setXHR_') {
var val = value(this);
// fix for angular < 1.2.0
if (val instanceof Function) {
val(this);
}
} else {
orig.apply(this, arguments);
}
};
})(window.XMLHttpRequest.prototype.setRequestHeader);
}
var ngFileUpload = angular.module('ngFileUpload', []);
ngFileUpload.version = '12.2.13';
ngFileUpload.service('UploadBase', ['$http', '$q', '$timeout', function ($http, $q, $timeout) {
var upload = this;
upload.promisesCount = 0;
this.isResumeSupported = function () {
return window.Blob && window.Blob.prototype.slice;
};
var resumeSupported = this.isResumeSupported();
function sendHttp(config) {
config.method = config.method || 'POST';
config.headers = config.headers || {};
var deferred = config._deferred = config._deferred || $q.defer();
var promise = deferred.promise;
function notifyProgress(e) {
if (deferred.notify) {
deferred.notify(e);
}
if (promise.progressFunc) {
$timeout(function () {
promise.progressFunc(e);
});
}
}
function getNotifyEvent(n) {
if (config._start != null && resumeSupported) {
return {
loaded: n.loaded + config._start,
total: (config._file && config._file.size) || n.total,
type: n.type, config: config,
lengthComputable: true, target: n.target
};
} else {
return n;
}
}
if (!config.disableProgress) {
config.headers.__setXHR_ = function () {
return function (xhr) {
if (!xhr || !xhr.upload || !xhr.upload.addEventListener) return;
config.__XHR = xhr;
if (config.xhrFn) config.xhrFn(xhr);
xhr.upload.addEventListener('progress', function (e) {
e.config = config;
notifyProgress(getNotifyEvent(e));
}, false);
//fix for firefox not firing upload progress end, also IE8-9
xhr.upload.addEventListener('load', function (e) {
if (e.lengthComputable) {
e.config = config;
notifyProgress(getNotifyEvent(e));
}
}, false);
};
};
}
function uploadWithAngular() {
$http(config).then(function (r) {
if (resumeSupported && config._chunkSize && !config._finished && config._file) {
var fileSize = config._file && config._file.size || 0;
notifyProgress({
loaded: Math.min(config._end, fileSize),
total: fileSize,
config: config,
type: 'progress'
}
);
upload.upload(config, true);
} else {
if (config._finished) delete config._finished;
deferred.resolve(r);
}
}, function (e) {
deferred.reject(e);
}, function (n) {
deferred.notify(n);
}
);
}
if (!resumeSupported) {
uploadWithAngular();
} else if (config._chunkSize && config._end && !config._finished) {
config._start = config._end;
config._end += config._chunkSize;
uploadWithAngular();
} else if (config.resumeSizeUrl) {
$http.get(config.resumeSizeUrl).then(function (resp) {
if (config.resumeSizeResponseReader) {
config._start = config.resumeSizeResponseReader(resp.data);
} else {
config._start = parseInt((resp.data.size == null ? resp.data : resp.data.size).toString());
}
if (config._chunkSize) {
config._end = config._start + config._chunkSize;
}
uploadWithAngular();
}, function (e) {
throw e;
});
} else if (config.resumeSize) {
config.resumeSize().then(function (size) {
config._start = size;
if (config._chunkSize) {
config._end = config._start + config._chunkSize;
}
uploadWithAngular();
}, function (e) {
throw e;
});
} else {
if (config._chunkSize) {
config._start = 0;
config._end = config._start + config._chunkSize;
}
uploadWithAngular();
}
promise.success = function (fn) {
promise.then(function (response) {
fn(response.data, response.status, response.headers, config);
});
return promise;
};
promise.error = function (fn) {
promise.then(null, function (response) {
fn(response.data, response.status, response.headers, config);
});
return promise;
};
promise.progress = function (fn) {
promise.progressFunc = fn;
promise.then(null, null, function (n) {
fn(n);
});
return promise;
};
promise.abort = promise.pause = function () {
if (config.__XHR) {
$timeout(function () {
config.__XHR.abort();
});
}
return promise;
};
promise.xhr = function (fn) {
config.xhrFn = (function (origXhrFn) {
return function () {
if (origXhrFn) origXhrFn.apply(promise, arguments);
fn.apply(promise, arguments);
};
})(config.xhrFn);
return promise;
};
upload.promisesCount++;
if (promise['finally'] && promise['finally'] instanceof Function) {
promise['finally'](function () {
upload.promisesCount--;
});
}
return promise;
}
this.isUploadInProgress = function () {
return upload.promisesCount > 0;
};
this.rename = function (file, name) {
file.ngfName = name;
return file;
};
this.jsonBlob = function (val) {
if (val != null && !angular.isString(val)) {
val = JSON.stringify(val);
}
var blob = new window.Blob([val], { type: 'application/json' });
blob._ngfBlob = true;
return blob;
};
this.json = function (val) {
return angular.toJson(val);
};
function copy(obj) {
var clone = {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = obj[key];
}
}
return clone;
}
this.isFile = function (file) {
return file != null && (file instanceof window.Blob || (file.flashId && file.name && file.size));
};
this.upload = function (config, internal) {
function toResumeFile(file, formData) {
if (file._ngfBlob) return file;
config._file = config._file || file;
if (config._start != null && resumeSupported) {
if (config._end && config._end >= file.size) {
config._finished = true;
config._end = file.size;
}
var slice = file.slice(config._start, config._end || file.size);
slice.name = file.name;
slice.ngfName = file.ngfName;
if (config._chunkSize) {
formData.append('_chunkSize', config._chunkSize);
formData.append('_currentChunkSize', config._end - config._start);
formData.append('_chunkNumber', Math.floor(config._start / config._chunkSize));
formData.append('_totalSize', config._file.size);
}
return slice;
}
return file;
}
function addFieldToFormData(formData, val, key) {
if (val !== undefined) {
if (angular.isDate(val)) {
val = val.toISOString();
}
if (angular.isString(val)) {
formData.append(key, val);
} else if (upload.isFile(val)) {
var file = toResumeFile(val, formData);
var split = key.split(',');
if (split[1]) {
file.ngfName = split[1].replace(/^\s+|\s+$/g, '');
key = split[0];
}
config._fileKey = config._fileKey || key;
formData.append(key, file, file.ngfName || file.name);
} else {
if (angular.isObject(val)) {
if (val.$$ngfCircularDetection) throw 'ngFileUpload: Circular reference in config.data. Make sure specified data for Upload.upload() has no circular reference: ' + key;
val.$$ngfCircularDetection = true;
try {
for (var k in val) {
if (val.hasOwnProperty(k) && k !== '$$ngfCircularDetection') {
var objectKey = config.objectKey == null ? '[i]' : config.objectKey;
if (val.length && parseInt(k) > -1) {
objectKey = config.arrayKey == null ? objectKey : config.arrayKey;
}
addFieldToFormData(formData, val[k], key + objectKey.replace(/[ik]/g, k));
}
}
} finally {
delete val.$$ngfCircularDetection;
}
} else {
formData.append(key, val);
}
}
}
}
function digestConfig() {
config._chunkSize = upload.translateScalars(config.resumeChunkSize);
config._chunkSize = config._chunkSize ? parseInt(config._chunkSize.toString()) : null;
config.headers = config.headers || {};
config.headers['Content-Type'] = undefined;
config.transformRequest = config.transformRequest ?
(angular.isArray(config.transformRequest) ?
config.transformRequest : [config.transformRequest]) : [];
config.transformRequest.push(function (data) {
var formData = new window.FormData(), key;
data = data || config.fields || {};
if (config.file) {
data.file = config.file;
}
for (key in data) {
if (data.hasOwnProperty(key)) {
var val = data[key];
if (config.formDataAppender) {
config.formDataAppender(formData, key, val);
} else {
addFieldToFormData(formData, val, key);
}
}
}
return formData;
});
}
if (!internal) config = copy(config);
if (!config._isDigested) {
config._isDigested = true;
digestConfig();
}
return sendHttp(config);
};
this.http = function (config) {
config = copy(config);
config.transformRequest = config.transformRequest || function (data) {
if ((window.ArrayBuffer && data instanceof window.ArrayBuffer) || data instanceof window.Blob) {
return data;
}
return $http.defaults.transformRequest[0].apply(this, arguments);
};
config._chunkSize = upload.translateScalars(config.resumeChunkSize);
config._chunkSize = config._chunkSize ? parseInt(config._chunkSize.toString()) : null;
return sendHttp(config);
};
this.translateScalars = function (str) {
if (angular.isString(str)) {
if (str.search(/kb/i) === str.length - 2) {
return parseFloat(str.substring(0, str.length - 2) * 1024);
} else if (str.search(/mb/i) === str.length - 2) {
return parseFloat(str.substring(0, str.length - 2) * 1048576);
} else if (str.search(/gb/i) === str.length - 2) {
return parseFloat(str.substring(0, str.length - 2) * 1073741824);
} else if (str.search(/b/i) === str.length - 1) {
return parseFloat(str.substring(0, str.length - 1));
} else if (str.search(/s/i) === str.length - 1) {
return parseFloat(str.substring(0, str.length - 1));
} else if (str.search(/m/i) === str.length - 1) {
return parseFloat(str.substring(0, str.length - 1) * 60);
} else if (str.search(/h/i) === str.length - 1) {
return parseFloat(str.substring(0, str.length - 1) * 3600);
}
}
return str;
};
this.urlToBlob = function (url) {
var defer = $q.defer();
$http({ url: url, method: 'get', responseType: 'arraybuffer' }).then(function (resp) {
var arrayBufferView = new Uint8Array(resp.data);
var type = resp.headers('content-type') || 'image/WebP';
var blob = new window.Blob([arrayBufferView], { type: type });
var matches = url.match(/.*\/(.+?)(\?.*)?$/);
if (matches.length > 1) {
blob.name = matches[1];
}
defer.resolve(blob);
}, function (e) {
defer.reject(e);
});
return defer.promise;
};
this.setDefaults = function (defaults) {
this.defaults = defaults || {};
};
this.defaults = {};
this.version = ngFileUpload.version;
}
]);
ngFileUpload.service('Upload', ['$parse', '$timeout', '$compile', '$q', 'UploadExif', function ($parse, $timeout, $compile, $q, UploadExif) {
var upload = UploadExif;
upload.getAttrWithDefaults = function (attr, name) {
if (attr[name] != null) return attr[name];
var def = upload.defaults[name];
return (def == null ? def : (angular.isString(def) ? def : JSON.stringify(def)));
};
upload.attrGetter = function (name, attr, scope, params) {
var attrVal = this.getAttrWithDefaults(attr, name);
if (scope) {
try {
if (params) {
return $parse(attrVal)(scope, params);
} else {
return $parse(attrVal)(scope);
}
} catch (e) {
// hangle string value without single qoute
if (name.search(/min|max|pattern/i)) {
return attrVal;
} else {
throw e;
}
}
} else {
return attrVal;
}
};
upload.shouldUpdateOn = function (type, attr, scope) {
var modelOptions = upload.attrGetter('ngfModelOptions', attr, scope);
if (modelOptions && modelOptions.updateOn) {
return modelOptions.updateOn.split(' ').indexOf(type) > -1;
}
return true;
};
upload.emptyPromise = function () {
var d = $q.defer();
var args = arguments;
$timeout(function () {
d.resolve.apply(d, args);
});
return d.promise;
};
upload.rejectPromise = function () {
var d = $q.defer();
var args = arguments;
$timeout(function () {
d.reject.apply(d, args);
});
return d.promise;
};
upload.happyPromise = function (promise, data) {
var d = $q.defer();
promise.then(function (result) {
d.resolve(result);
}, function (error) {
$timeout(function () {
throw error;
});
d.resolve(data);
});
return d.promise;
};
function applyExifRotations(files, attr, scope) {
var promises = [upload.emptyPromise()];
angular.forEach(files, function (f, i) {
if (f.type.indexOf('image/jpeg') === 0 && upload.attrGetter('ngfFixOrientation', attr, scope, { $file: f })) {
promises.push(upload.happyPromise(upload.applyExifRotation(f), f).then(function (fixedFile) {
files.splice(i, 1, fixedFile);
}));
}
});
return $q.all(promises);
}
function resizeFile(files, attr, scope, ngModel) {
var resizeVal = upload.attrGetter('ngfResize', attr, scope);
if (!resizeVal || !upload.isResizeSupported() || !files.length) return upload.emptyPromise();
if (resizeVal instanceof Function) {
var defer = $q.defer();
return resizeVal(files).then(function (p) {
resizeWithParams(p, files, attr, scope, ngModel).then(function (r) {
defer.resolve(r);
}, function (e) {
defer.reject(e);
});
}, function (e) {
defer.reject(e);
});
} else {
return resizeWithParams(resizeVal, files, attr, scope, ngModel);
}
}
function resizeWithParams(params, files, attr, scope, ngModel) {
var promises = [upload.emptyPromise()];
function handleFile(f, i) {
if (f.type.indexOf('image') === 0) {
if (params.pattern && !upload.validatePattern(f, params.pattern)) return;
params.resizeIf = function (width, height) {
return upload.attrGetter('ngfResizeIf', attr, scope,
{ $width: width, $height: height, $file: f });
};
var promise = upload.resize(f, params);
promises.push(promise);
promise.then(function (resizedFile) {
files.splice(i, 1, resizedFile);
}, function (e) {
f.$error = 'resize';
(f.$errorMessages = (f.$errorMessages || {})).resize = true;
f.$errorParam = (e ? (e.message ? e.message : e) + ': ' : '') + (f && f.name);
ngModel.$ngfValidations.push({ name: 'resize', valid: false });
upload.applyModelValidation(ngModel, files);
});
}
}
for (var i = 0; i < files.length; i++) {
handleFile(files[i], i);
}
return $q.all(promises);
}
upload.updateModel = function (ngModel, attr, scope, fileChange, files, evt, noDelay) {
function update(files, invalidFiles, newFiles, dupFiles, isSingleModel) {
attr.$$ngfPrevValidFiles = files;
attr.$$ngfPrevInvalidFiles = invalidFiles;
var file = files && files.length ? files[0] : null;
var invalidFile = invalidFiles && invalidFiles.length ? invalidFiles[0] : null;
if (ngModel) {
upload.applyModelValidation(ngModel, files);
ngModel.$setViewValue(isSingleModel ? file : files);
}
if (fileChange) {
$parse(fileChange)(scope, {
$files: files,
$file: file,
$newFiles: newFiles,
$duplicateFiles: dupFiles,
$invalidFiles: invalidFiles,
$invalidFile: invalidFile,
$event: evt
});
}
var invalidModel = upload.attrGetter('ngfModelInvalid', attr);
if (invalidModel) {
$timeout(function () {
$parse(invalidModel).assign(scope, isSingleModel ? invalidFile : invalidFiles);
});
}
$timeout(function () {
// scope apply changes
});
}
var allNewFiles, dupFiles = [], prevValidFiles, prevInvalidFiles,
invalids = [], valids = [];
function removeDuplicates() {
function equals(f1, f2) {
return f1.name === f2.name && (f1.$ngfOrigSize || f1.size) === (f2.$ngfOrigSize || f2.size) &&
f1.type === f2.type;
}
function isInPrevFiles(f) {
var j;
for (j = 0; j < prevValidFiles.length; j++) {
if (equals(f, prevValidFiles[j])) {
return true;
}
}
for (j = 0; j < prevInvalidFiles.length; j++) {
if (equals(f, prevInvalidFiles[j])) {
return true;
}
}
return false;
}
if (files) {
allNewFiles = [];
dupFiles = [];
for (var i = 0; i < files.length; i++) {
if (isInPrevFiles(files[i])) {
dupFiles.push(files[i]);
} else {
allNewFiles.push(files[i]);
}
}
}
}
function toArray(v) {
return angular.isArray(v) ? v : [v];
}
function resizeAndUpdate() {
function updateModel() {
$timeout(function () {
update(keep ? prevValidFiles.concat(valids) : valids,
keep ? prevInvalidFiles.concat(invalids) : invalids,
files, dupFiles, isSingleModel);
}, options && options.debounce ? options.debounce.change || options.debounce : 0);
}
var resizingFiles = validateAfterResize ? allNewFiles : valids;
resizeFile(resizingFiles, attr, scope, ngModel).then(function () {
if (validateAfterResize) {
upload.validate(allNewFiles, keep ? prevValidFiles.length : 0, ngModel, attr, scope)
.then(function (validationResult) {
valids = validationResult.validsFiles;
invalids = validationResult.invalidsFiles;
updateModel();
});
} else {
updateModel();
}
}, function () {
for (var i = 0; i < resizingFiles.length; i++) {
var f = resizingFiles[i];
if (f.$error === 'resize') {
var index = valids.indexOf(f);
if (index > -1) {
valids.splice(index, 1);
invalids.push(f);
}
updateModel();
}
}
});
}
prevValidFiles = attr.$$ngfPrevValidFiles || [];
prevInvalidFiles = attr.$$ngfPrevInvalidFiles || [];
if (ngModel && ngModel.$modelValue) {
prevValidFiles = toArray(ngModel.$modelValue);
}
var keep = upload.attrGetter('ngfKeep', attr, scope);
allNewFiles = (files || []).slice(0);
if (keep === 'distinct' || upload.attrGetter('ngfKeepDistinct', attr, scope) === true) {
removeDuplicates(attr, scope);
}
var isSingleModel = !keep && !upload.attrGetter('ngfMultiple', attr, scope) && !upload.attrGetter('multiple', attr);
if (keep && !allNewFiles.length) return;
upload.attrGetter('ngfBeforeModelChange', attr, scope, {
$files: files,
$file: files && files.length ? files[0] : null,
$newFiles: allNewFiles,
$duplicateFiles: dupFiles,
$event: evt
});
var validateAfterResize = upload.attrGetter('ngfValidateAfterResize', attr, scope);
var options = upload.attrGetter('ngfModelOptions', attr, scope);
upload.validate(allNewFiles, keep ? prevValidFiles.length : 0, ngModel, attr, scope)
.then(function (validationResult) {
if (noDelay) {
update(allNewFiles, [], files, dupFiles, isSingleModel);
} else {
if ((!options || !options.allowInvalid) && !validateAfterResize) {
valids = validationResult.validFiles;
invalids = validationResult.invalidFiles;
} else {
valids = allNewFiles;
}
if (upload.attrGetter('ngfFixOrientation', attr, scope) && upload.isExifSupported()) {
applyExifRotations(valids, attr, scope).then(function () {
resizeAndUpdate();
});
} else {
resizeAndUpdate();
}
}
});
};
return upload;
}]);
ngFileUpload.directive('ngfSelect', ['$parse', '$timeout', '$compile', 'Upload', function ($parse, $timeout, $compile, Upload) {
var generatedElems = [];
function isDelayedClickSupported(ua) {
// fix for android native browser < 4.4 and safari windows
var m = ua.match(/Android[^\d]*(\d+)\.(\d+)/);
if (m && m.length > 2) {
var v = Upload.defaults.androidFixMinorVersion || 4;
return parseInt(m[1]) < 4 || (parseInt(m[1]) === v && parseInt(m[2]) < v);
}
// safari on windows
return ua.indexOf('Chrome') === -1 && /.*Windows.*Safari.*/.test(ua);
}
function linkFileSelect(scope, elem, attr, ngModel, $parse, $timeout, $compile, upload) {
/** @namespace attr.ngfSelect */
/** @namespace attr.ngfChange */
/** @namespace attr.ngModel */
/** @namespace attr.ngfModelOptions */
/** @namespace attr.ngfMultiple */
/** @namespace attr.ngfCapture */
/** @namespace attr.ngfValidate */
/** @namespace attr.ngfKeep */
var attrGetter = function (name, scope) {
return upload.attrGetter(name, attr, scope);
};
function isInputTypeFile() {
return elem[0].tagName.toLowerCase() === 'input' && attr.type && attr.type.toLowerCase() === 'file';
}
function fileChangeAttr() {
return attrGetter('ngfChange') || attrGetter('ngfSelect');
}
function changeFn(evt) {
if (upload.shouldUpdateOn('change', attr, scope)) {
var fileList = evt.__files_ || (evt.target && evt.target.files), files = [];
/* Handle duplicate call in IE11 */
if (!fileList) return;
for (var i = 0; i < fileList.length; i++) {
files.push(fileList[i]);
}
upload.updateModel(ngModel, attr, scope, fileChangeAttr(),
files.length ? files : null, evt);
}
}
upload.registerModelChangeValidator(ngModel, attr, scope);
var unwatches = [];
if (attrGetter('ngfMultiple')) {
unwatches.push(scope.$watch(attrGetter('ngfMultiple'), function () {
fileElem.attr('multiple', attrGetter('ngfMultiple', scope));
}));
}
if (attrGetter('ngfCapture')) {
unwatches.push(scope.$watch(attrGetter('ngfCapture'), function () {
fileElem.attr('capture', attrGetter('ngfCapture', scope));
}));
}
if (attrGetter('ngfAccept')) {
unwatches.push(scope.$watch(attrGetter('ngfAccept'), function () {
fileElem.attr('accept', attrGetter('ngfAccept', scope));
}));
}
unwatches.push(attr.$observe('accept', function () {
fileElem.attr('accept', attrGetter('accept'));
}));
function bindAttrToFileInput(fileElem, label) {
function updateId(val) {
fileElem.attr('id', 'ngf-' + val);
label.attr('id', 'ngf-label-' + val);
}
for (var i = 0; i < elem[0].attributes.length; i++) {
var attribute = elem[0].attributes[i];
if (attribute.name !== 'type' && attribute.name !== 'class' && attribute.name !== 'style') {
if (attribute.name === 'id') {
updateId(attribute.value);
unwatches.push(attr.$observe('id', updateId));
} else {
fileElem.attr(attribute.name, (!attribute.value && (attribute.name === 'required' ||
attribute.name === 'multiple')) ? attribute.name : attribute.value);
}
}
}
}
function createFileInput() {
if (isInputTypeFile()) {
return elem;
}
var fileElem = angular.element('');
var label = angular.element('');
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 ? '');
return l.find("a").attr("href", "javascript:void(0);"), s.content = l, s.title = l.find(".title"), s.applyBtn = l.find(".js-save-button"), s.mobileTitle = l.find(".base-selector__header-title"), s.choseAll = l.find(".chose-all"), s.choseMinute = l.find(".chose-minute"), s.choseHour = l.find(".chose-hour"), s.hourShow = l.find(".js-hour-show"), s.minuteShow = l.find(".js-minute-show"), s.update = function () {
return bstptid.val(i(this.hour) + ":" + i(this.minute)), this.minuteShow.text(i(this.minute)), this.hourShow.text(i(this.hour)), this.inputTarget.$timepickerUpdate(), this
}, s.bindEvent = function () {
var t = this;
t.hasBind || (t.hasBind = !0, this.content.on("click", ".js-minus-minute", function () {
t.minute = t.minute - t.minuteStep;
if (t.minute < 0) {
t.minute = t.minute + 60;
}
t.update();
}).on("click", ".js-plus-minute", function () {
t.minute = t.minute + t.minuteStep;
if (t.minute >= 60) {
t.minute = t.minute - 60;
}
t.update();
}).on("click", ".js-plus-houer", function () {
t.hour >= 23 ? t.hour = 0 : t.hour++, t.update()
}).on("click", ".js-minus-houer", function () {
t.hour <= 0 ? t.hour = 23 : t.hour--, t.update()
}).on("click", ".js-minute-cell", function () {
t.minute = +this.getAttribute("data-val"), t.update(), t.choseMinute.hide(), t.choseAll.show(), t.title.text(t.headerText)
}).on("click", ".js-hour-cell", function () {
t.hour = +this.getAttribute("data-val"), t.update(), t.choseHour.hide(), t.choseAll.show(), t.title.text(t.headerText)
}).on("click", function (t) {
t.stopPropagation()
}), t.hourShow.on("click", function () {
t.choseAll.hide(), t.choseHour.show(), t.title.text(t.headerText)
}), t.minuteShow.on("click", function () {
t.choseAll.hide(), t.choseMinute.show(), t.title.text(t.headerText)
}))
}, t.timepicker = s, t.fn.timepicker = function (i) {
t.timepicker.minuteStep = i.minuteStep !== undefined ? i.minuteStep : defaultMinuteStep;
t.timepicker.headerText = i.headerText !== undefined ? i.headerText : defaultHeaderText;
t.timepicker.applyText = i.applyText !== undefined ? i.applyText : defaultApplyText;
if (this[0].nodeName && "INPUT" === this[0].nodeName) return this.$timepickerUpdate = n, this.off("keydown").on("keydown", function () {
return !1
}), this.update = function (i) {
t.isFunction(i) ? this.$timepickerUpdate = i : this.$timepickerUpdate = n
}, this
}, t.fn.showTimepicker = function (i) {
this.$timepickerUpdate = function () { };
var s, o, c = this, l = t.timepicker, u = t("html");
var n = this[0].value;
bstptid = $(this[0]);
e.test(n) ? (n = n.split(":"), s = +n[0], o = +n[1]) : (n = new Date, s = n.getHours(), o = n.getMinutes());
$(l.title).html(l.headerText);
$(l.mobileTitle).html(l.headerText);
$(l.applyBtn).html(l.applyText);
l.inputTarget = c, l.content.insertAfter(this[0].parentElement),
l.hour = s, l.minute = o, l.choseAll.show(), l.choseHour.hide(), l.choseMinute.hide(), l.update(), t.timepicker.bindEvent();
}, t.fn.closeTimepicker = function (i) {
var c = this, l = t.timepicker;
l.content.off().remove(), l.hasBind = !1;
}, t
});