angular.module('fileUploader', []).directive('fileUploader', ['fileAPI', 'baseAPI', '$rootScope', function (fileAPI, baseAPI, $rootScope) {
return {
compile: function (elem, attr) {
return {
pre: function ($scope, elem, attrs, ctrl, transclude) {
$scope.remove = function ($index) {
var uploadedFileIndex = _.indexOf(fileAPI.uploadedFiles, $scope.files[$index].FileName);
if (uploadedFileIndex >= 0) {
fileAPI.uploadedFiles.splice(uploadedFileIndex, 1);
};
$scope.files.splice($index, 1);
$rootScope.$broadcast('uploader-' + $scope.Id + 'changeUpload');
elem.find('#uploader-filename-' + $scope.Id).val('');
};
$('#uploader-filename-' + $scope.Id).val("");
$scope.Id = $scope.$id;
$scope.root = $rootScope;
angular.forEach($scope.files, function (file) {
var uploadedFileIndex = _.indexOf(fileAPI.uploadedFiles, file.FileName);
if (uploadedFileIndex < 0) {
fileAPI.uploadedFiles.push(file.FileName);
};
});
},
post: function ($scope, elem, attrs, ctrl, transclude) {
var isJsonString = function (str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
$scope.requiredDocuments = (typeof $scope.requiredDocuments === "undefined") ? false : true;
var clearFileInput = function () {
//Fix clearing file input IE8
$('#uploader-' + $scope.Id).val(null);
var clone = $('#uploader-' + $scope.Id).clone(true).off();
$('#uploader-' + $scope.Id).replaceWith(clone);
};
var getErrorMessage = function (errors) {
if (typeof errors === 'string')
return errors;
return errors[0];
}
var onSuccess = function (response) {
if (isJsonString(response))
response = $.parseJSON(response);
if ($scope.files == null)
$scope.files = [];
elem.find('#uploader-filename-' + $scope.Id).val("");
if (response.Success) {
response.Data.FileName = decodeURIComponent(response.Data.FileName);
response.Data.Name = decodeURIComponent(response.Data.Name);
response.Data.IsLoaded = true;
if ($scope.documentTypeId)
response.Data.DocumentTypeId = $scope.documentTypeId;
updateArray($scope.files, response.Data);
} else {
var decodeError = decodeURIComponent(response.Errors);
ShowMessage("Произошла ошибка", getErrorMessage(decodeError));
for (var i = 0; i < $scope.files.length; i++) {
if ($scope.files[i].FileName === response.Data.FileName) {
$scope.files.splice(i, 1);
}
}
for (var j = 0; j < fileAPI.uploadedFiles.length; j++) {
if (fileAPI.uploadedFiles[j] === response.Data.FileName) {
fileAPI.uploadedFiles.splice(j, 1);
}
}
$rootScope.$broadcast('uploader-' + $scope.Id + 'changeUpload');
}
fileAPI.filesInProgress--;
$rootScope.$broadcast('file-loading', fileAPI.filesInProgress);
clearFileInput();
$scope.$apply();
};
var updateArray = function (array, value) {
for (var i = 0; i < array.length; i++) {
if (array[i].FileName === value.FileName) {
array[i] = value;
}
}
}
var onError = function (response) {
if (response.status === 401) {
var $dialogUserInactiveInfo = $("#dialogUserInactiveInfo");
if ($dialogUserInactiveInfo.hasClass('ui-dialog-content')) {
$dialogUserInactiveInfo.dialog('open');
}
else {
$dialogUserInactiveInfo.dialog({
dialogClass: 'no-close',
closeOnEscape: false,
modal: true,
width: 500,
buttons: [
{
text: "ОК",
click: function () {
$(this).dialog("close");
window.location.reload();
}
}
]
});
}
}
};
var options = {
success: onSuccess,
error: onError
};
var checkExtension = function (file) {
var regex = /(?:\.([^.]+))?$/;
var extension = (regex.exec(file)[1] || "").toLowerCase();
var filename = file.match(/[^\\/]*$/)[0];
if (_.indexOf($scope.settings.allowedExtensions, extension) < 0) {
ShowError("У " +
filename +
" неподдерживаемый формат файла. Поддерживаются следующие форматы файлов: " +
$scope.settings.allowedExtensions.join(", ") +
'.');
return false;
}
return true;
};
var isFileAlreadyUploaded = function (fileName) {
return typeof ($scope.files) !== "undefined" && _.where($scope.files, { FileName: fileName }).length > 0;
};
var renameFileTwin = function (fileName) {
return new Promise(function (resolve, reject) {
var generatedFileName;
var newName = fileName;
if (_.indexOf(fileAPI.uploadedFiles, fileName) >= 0 || isFileAlreadyUploaded(fileName)) {
generatedFileName = fileAPI.generateNewFileName(fileName, fileAPI.uploadedFiles);
if (isFileAlreadyUploaded(generatedFileName)) {
generatedFileName = fileAPI.generateNewFileName(generatedFileName, fileAPI.uploadedFiles);
};
newName = generatedFileName;
ShowMessage('Предупреждение', 'Уже был загружен файл с именем ' +
fileName +
'. Загружаемый файл будет переименован в ' +
generatedFileName +
'.', null, function () {
resolve(newName);
});
elem.find('#uploader-filename-' + $scope.Id).val(newName);
} else {
resolve(newName);
}
});
};
var checkFileLength = function (uploader) {
if (typeof $('#uploader-' + $scope.Id)[0].value != "undefined" && uploader) {
var fileSize;
if(typeof uploader[0].files === "undefined"){
//Расчет размера файла в IE без FileAPI
try {
var objFSO = new ActiveXObject("Scripting.FileSystemObject");
var filePath = $('#uploader-' + $scope.Id)[0].value;
var objFile = objFSO.getFile(filePath);
fileSize = objFile.size; //size in kB
} catch (e) {
//Если уровень безопасности не даёт выполниться ActiveXObject, то говорим что валидация пройдена.
fileSize = 10;
};
} else {
fileSize = uploader[0].files[0].size;
}
if (fileSize > $scope.settings.maxFileSize) {
ShowError("Размер документа не должен превышать 50 мб");
return false;
}
if (fileSize === 0) {
var filename = uploader.val().match(/[^\\/]*$/)[0];
ShowError("Содержимое документа " +
filename +
" отсутсвует. Выберите, пожалуйста, подходящий документ");
return false;
}
}
return true;
};
var uploadFile = function (event) {
var uploader = $('#uploader-' + $scope.Id);
if (uploader.val() !== "" && uploader.val() !== null) {
var filename = uploader.val().match(/[^\\/]*$/)[0];
if (checkExtension(uploader.val()) && checkFileLength(uploader)) {
if ($scope.files == null) $scope.files = [];
renameFileTwin(filename).then(function (newName) {
$rootScope.$safeApply(function () {
$scope.files.push({
FileName: newName,
IsLoaded: false
});
fileAPI.uploadedFiles.push(newName);
$rootScope.$broadcast('uploader-' + $scope.Id + 'changeUpload');
fileAPI.filesInProgress++;
$rootScope.$broadcast('file-loading', fileAPI.filesInProgress);
});
console.dir(options);
$(elem.find('#uploaderForm-' + $scope.Id)).ajaxSubmit(options);
});
} else {
clearFileInput();
}
}
};
$scope.$watch('files', function (newValue, oldValue) {
if (newValue === oldValue && $scope.files instanceof Array) {
$.each($scope.files, function (i, f) { f.IsLoaded = true; });
}
});
$(elem).change(uploadFile);
}
}
},
restrict: 'EA',
replace: true,
templateUrl: '/static/Scripts/Common/Angular/Directives/Templates/UploaderTemplate.html',
scope: {
settings: '=uploaderSettings',
files: '=ngModel',
documentTypeId: '=ngDocumentType',
requiredDocuments: '=isRequired',
requiredDocumentsType: '=documentsType'
}
}
}]);