<!DOCTYPE html>
<html>
<head>
<title>Ng Uploader</title>
<link href="https://file.myfontastic.com/SLzQsLcd7FmmzjBYTcyVW3/icons.css" rel="stylesheet">
<link rel="stylesheet" href="file-uploader.css">
<link rel="stylesheet" href="style.css">
</head>
<body ng-app="app" ng-controller="Controller as Ctrl">
<form ng-submit="Ctrl.submit($event)">
<file-uploader file="Ctrl.user.file" base-color="#ccc" active-color="green"></file-uploader>
<button type="submit">Enviar</button>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.9/angular.min.js"></script>
<script src="ng-file-uploader.js"></script>
<script src="app.js"></script>
</body>
</html>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
body {
align-items: center;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
button {
margin-top: 2em;
}
**Angular 1** directive for a custom input file with live preview and drag & drop capabilities
/* File Uploader Styles */
.uploader input {
display: none;
}
.uploader {
-webkit-align-items: center;
align-items: center;
background-color: #efefef;
background-color: rgba(0, 0, 0, 0.02);
cursor: pointer;
display: -webkit-flex;
display: flex;
height: 300px;
-webkit-justify-content: center;
justify-content: center;
outline: 3px dashed #ccc;
outline-offset: 5px;
position: relative;
width: 300px;
}
.uploader img,
.uploader .icon {
pointer-events: none;
}
.uploader,
.uploader .icon {
-webkit-transition: all 100ms ease-in;
-moz-transition: all 100ms ease-in;
-ms-transition: all 100ms ease-in;
-o-transition: all 100ms ease-in;
transition: all 100ms ease-in;
}
.uploader .icon {
color: #eee;
color: rgba(0, 0, 0, 0.2);
font-size: 5em;
}
.uploader img {
left: 50%;
opacity: 0;
max-height: 100%;
max-width: 100%;
position: absolute;
top: 50%;
-webkit-transition: all 300ms ease-in;
-moz-transition: all 300ms ease-in;
-ms-transition: all 300ms ease-in;
-o-transition: all 300ms ease-in;
transition: all 300ms ease-in;
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
z-index: -1;
}
.uploader img.loaded {
opacity: 1;
}
(function() {
'use strict';
angular.module('ngUploader', [])
.directive('fileUploader', FileUploader);
function FileUploader() {
return {
restrict: 'E',
replace: true,
scope: {
activeColor: '@',
baseColor: '@',
file: '='
},
template: "" +
"<label class='uploader' ondragover='return false'>" +
"<img />" +
"<i class='icon icon-upload'></i>" +
"<input type='file' accept='image/*' />" +
"</label>",
link: function(scope, element, attrs) {
var settings = angular.extend({
baseColor: '#ccc',
activeColor: 'green',
overlayColor: 'rgba(255,255,255,0.5)'
}, scope);
var $label = element,
$fileInput = $label.find('input'),
$icon = $label.find('i'),
$img = $label.find('img');
_setInactive();
suscribe();
function suscribe() {
$fileInput.on('change', _handleInputChange);
$img.on('load', _handleImageLoaded);
$label.on('dragenter', _handleDragEnter);
$label.on('dragleave', _handleDragLeave);
$label.on('drop', _handleDrop);
}
function _handleDragEnter(e) {
e.preventDefault();
_setActive();
}
function _handleDragLeave(e) {
e.preventDefault();
_setInactive();
}
function _handleDrop(e) {
e.preventDefault();
_setInactive();
$fileInput[0].files = e.dataTransfer.files;
_handleInputChange();
}
function _handleImageLoaded() {
if (!$img.hasClass('loaded')) {
$img.addClass('loaded');
}
_setInactive();
}
function _handleInputChange(e) {
var file = (undefined !== e) ? e.target.files[0] : $fileInput[0].files[0];
var pattern = /image-*/;
var reader = new FileReader();
if (!file.type.match(pattern)) {
alert('invalid format');
return;
}
if ($label.hasClass('loaded')) {
$label.removeClass('loaded');
}
reader.onload = _handleReaderLoaded;
reader.readAsDataURL(file);
scope.file = file;
scope.$apply();
}
function _handleReaderLoaded(e) {
var reader = e.target;
$img[0].src = reader.result;
$label.addClass('loaded');
}
function _setActive() {
$label.css('outline-color', settings.activeColor);
$icon.css('color', settings.activeColor);
}
function _setInactive() {
$label.css('outline-color', settings.baseColor);
$icon.css('color', ($img.hasClass('loaded') ? settings.overlayColor : settings.baseColor));
}
}
}
}
}());
(function() {
'use strict';
angular.module('app', ['ngUploader'])
.controller('Controller', Controller);
Controller.$inject = ['$http'];
function Controller($http) {
var vm = this;
vm.user = { file: null };
vm.submit = function($event) {
$event.preventDefault();
$http.post('http://nowhere.com', vm.user, {
headers: { 'Content-Type': undefined },
transformRequest: function(data) {
if (undefined === data) return data;
var formData = new FormData();
angular.forEach(data, function(value, key) {
formData.append(key, value);
});
return formData;
}
});
}
}
}());