I am using angularjs file uploader given at "https://github.com/nervgh/angular-file-upload", so my js code look like this:
var urls = ['url1', 'url2'];
var uploaders = $scope.uploaders = urls.map(function(url) {
return new FileUploader({url: url});
});
$http.get('url.php').then(function(resp) {
$scope.images = resp.data.images; // images array
uploaders[0].addToQueue($scope.images[0]);
// add first img to 1st uploader
var i;
for(i=1;i<$scope.images.length;i++){
uploaders[1].addToQueue($scope.images[i]);
}
// append other images to 2nd uploader
});
Now I can get uploaders[0].queue.length = 1 but not the other proerties like uploaders[0].queue[0].file.name ,
any suggestions?
Related
Using Angular 1.x I want to provide a drag and drop box for uploading images. When the images have been dropped I want to show a preview in the front end.
This is my code:
dropbox.addEventListener("drop", function(evt) {
evt.stopPropagation();
evt.preventDefault();
$scope.$apply(function(){
$scope.dropText = 'Drop files here...';
$scope.dropClass = '';
});
var files = evt.dataTransfer.files;
if (files.length > 0) {
$scope.listing.listing_images = [];
$scope.imagepreview = [];
for (var i = 0; i < files.length; i++) {
// push the image to be uploaded
$scope.listing.listing_images.push(files[i]);
// push the image to be rendered
var reader = new FileReader();
reader.onload = function (e) {
$scope.imagepreview[i] = e.target.result;
}
reader.readAsDataURL(files[i]);
}
console.log($scope.imagepreview);
console.log($scope.imagepreview.length);
}
}, false);
If I drop say 3 images into the dropbox area and I console.log $scope.imagepreview I can see that the image is stored - so far so good!
[]
0: "data:image/jpeg;base64,/9j/4fzyRXhpZgAATU0AKgAAAAg"
1: "data:image/jpeg;base64,/9j/4f8ERXhpZgAATU0AKgAAAAg"
2: "data:image/jpeg;base64,/9j/4f+eRXhpZgAATU0AKgAAAAg"
length: 3
__proto__: Array(0)
Then on the very next line:
$scope.imagepreview.length 0
This makes no sense and looks like a bug to me, how can Scope object have data but also have a length of 0?
The problem is that in my template when I try to ng-repeat on the $scope.previewimages the object is empty so no images are rendered. Any ideas?
The code is missing an $apply block for the reader load event:
for (var i = 0; i < files.length; i++) {
// push the image to be uploaded
$scope.listing.listing_images.push(files[i]);
// push the image to be rendered
var reader = new FileReader();
reader.onload = function (e) {
//IMPORTANT
$scope.$apply(function() {
$scope.imagepreview[i] = e.target.result;
});
}
reader.readAsDataURL(files[i]);
}
When the FileReader load event handler modifies $scope, the AngularJS frame needs to digest the changes and update the DOM.
For more information, see
AngularJS Developer Guide - Integration with the browser event loop
I have a function that will determine if the gif is animated or non-animated. Everything is working fine, until i upload those gif to the server, and load it, the blob url is a empty string. How can i generate a blob url for this?
Due to the blob url being empty string, i get parameter 1 is not of type 'blob'
The function below determines if the gif is animated or not.
$scope.isNotAnimatedGIF = function(file) {
var reader = new FileReader();
return new Promise(function(resolve, reject) {
reader.onload = function (e) {
var gifInfo = gify.getInfo(reader.result);
if (gifInfo.images.length <= 1) {
file.animatedGIF = false;
resolve(true);
} else {
file.animatedGIF = true;
resolve(false);
}
}
reader.readAsArrayBuffer(file);
});
}
I am using Angular 1.4.10
Thank you !
You can use URL.createObjectURL() to create Blob url.
The URL.createObjectURL() static method creates a DOMString containing a URL representing the object given in the parameter. The URL lifetime is tied to the document in the window on which it was created. The new object URL represents the specified File object or Blob object.
DEMO
function createbloburl(file, type) {
var blob = new Blob([file], {
type: type || 'application/*'
});
file = window.URL.createObjectURL(blob);
return file;
}
document.querySelector('#file').addEventListener('change', function(e) {
var file = e.currentTarget.files[0];
if (file) {
file = createbloburl(file, file.type);
document.querySelector('iframe').src = file;
//console.log(file)
}
})
<input id="file" type="file">
<iframe src=""></iframe>
try this reader.readAsDataURL(Blob|File).
you can find more from here
I'm using drupal7 Photoswipe module which uses Photoswipe jQuery plugin to build a view and display a gallery of photos.
Currently Photoswipe allows only to display image title as image caption.
Also to display other text fields from the same content node, I add content text fields to the view and change their display to add a CSS class (.photo_text).
Then I modified openPhotoSwipe function within photoswipe.jquery.js to get the image parent html node ($image .parents("td:first") ) and select it's children having the (.photo_text) CSS class, to add them as image title.
openPhotoSwipe: function(index, galleryElement, options) {
var pswpElement = $('.pswp')[0];
var items = [];
options = options || Drupal.behaviors.photoswipe.photoSwipeOptions;
var images = galleryElement.find('a.photoswipe');
images.each(function (index) {
var $image = $(this);
var $eleme = $image.parents("td:first");
var $eleme_class = $eleme.children('.photo_text');
var $photo_text = "";
if ( !!$eleme_class){
for ( var i = 0; i < $eleme_class.length; i++ ){
$photo_text += $eleme_class[i].innerHTML;
}
}else{
$photo_text = "";
}
// end of add
size = $image.data('size') ? $image.data('size').split('x') : ['',''];
items.push(
{
src : $image.attr('href'),
w: size[0],
h: size[1],
title : $image.data('overlay-title') + $photo_text
}
);
})
I'm now wondering if it exists a simplest way to do the same thing without modifying this module?
I want to download an image file through XHR using the $http service provided by angularJS, and upload the response data (image data) to OSS(it is a service that host files provided by Alibaba) and it's api reference for put is:
which indicates that it will take a {String|Buffer|ReadStream} as the second parameter file,
but how can I transfer the response data so that I could make that a parameter for this put(name, file) method like:
$http.get("http://image.url/file.gif").then(
function success(response){
console.log("type of response.data is :" + typeof response.data);
oss.put("test.jpg", response.data); //<-- here will give an error
},
function fail(response){
console.log("error");
}
)
this will give a type error:
Any suggestion or answer is appreciated.
if you're getting the images via links all the time and you want to get the string data out of it, I've tried a small function that i hope it helps, it takes the link and puts to you the image data in base64 string format
function getBase64StringFromImgLink(imageSrc, imgType) {
var imageAsCanvas;
/*
* Creates a new image object from the src
* Uses the deferred pattern
*/
var createImage = function () {
var deferred = $.Deferred();
var img = new Image();
img.onload = function() {
deferred.resolve(img);
};
img.src = imageSrc;
return deferred.promise();
};
/*
* Create an Image, when loaded and start to resize
*/
$.when(createImage()).then(function (image) {
imageAsCanvas = document.createElement("canvas");
imageAsCanvas.width = image.width;
imageAsCanvas.height = image.height;
var ctx = imageAsCanvas.getContext("2d");
ctx.drawImage(image, 0, 0, imageAsCanvas.width, imageAsCanvas.height);
$scope.$apply(function($scope){
$scope.imageAsBase64String = imageAsCanvas.toDataURL(imgType);
oss.put("test.jpg", $scope.imageAsBase64String); //<-- here will be the data string i hope it works
});
}, function () {console.log('error creating an image')});
}
//How to call example
getBase64StringFromImgLink('images/george-avatar.jpg', 'image/jpeg');
<!--HTML -->
<img data-ng-src="{{imageAsBase64String}}" >
I am trying to preview images that are selected from input type file with multiple. For that i want list of file paths and using those paths I will preview images.
But here I used ng-src in img tag, and those paths are set on ng-src and also i want create img tag according to file selection using ng-repeat.
Suppose I will select 5 files on input type=file then create 5 img tag. Suppose I change files from 5 to 2, then all 5 img tags are removed and 2 img tags are created.
I don't know if ng-repeat is a right option for creation of img tag according to file selection or not?
below this is my myfileupload directive
App.directive('myFileUpload', function (fileService) {
return {link: function (scope, element, attrs) {
element.bind('change', function () {
var index;
var index_file = 0;
for (index = 0; index < element[0].files.length; index++) {
var file=element[0].files[index];
fileService.setFile(element[0].files[index], index_file, attrs.myFileUpload);
index_file++;
var src={};
/*src["src"]=element[0].files[index];*/
fileService.setFilePath(element[0].files[index], index_file, attrs.myFileUpload);
console.log(pathss);
path.push(src);
}
index_file = 0;
});
}
};
});
this is mys service
App.service('fileService', function () {
var fileService = {};
fileService.getFile = function (name) {
return file[name];
};
fileService.setFile = function (newFile, index, name) {
if (index === 0 && file[name] === undefined)
/*file[name] = [];*/
console.log(file);
file[name][index] = newFile;
/*console.log(name);*/
};
fileService.getFilePath = function (name) {
return filepath[name];
};
fileService.setFilePath = function (newFile, index, name) {
if (index === 0 && file[name] === undefined)
/*file[name] = [];*/
console.log(file);
filepath[name][index] = newFile.val;
/*console.log(name);*/
};
return fileService;
})
controller for how i am create a input type file
$scope.add=function(){
var name="descimg["+currentg1+"]";
var pathname="imgfile["+currentg1+"]";
file[name] = [];
var $div = angular.element("<div><label id='desccodeL["+currentg1+"]' for='desccodeL["+currentg1+"]''>Code "+currentg1+"</label><textarea rows='3' cols='6' id='desccode["+currentg1+"]' name='desccode["+currentg1+"]' ng-model='blog.desccode["+currentg1+"]''></textarea></div><div><label id='descimgL["+currentg1+"]' for='descimgL["+currentg1+"]'>Image "+currentg1+"</label><input type='file' id='descimg["+currentg1+"]' class='file' name='descimg["+currentg1+"]' my-file-upload='descimg["+currentg1+"]' multiple/></div>");
var e=document.getElementById("outerdiv");
var $div2=angular.element("<div ng repeat='path in "+fileService.getFilePath("descimg["+currentg1+"]"); +"'><img ng-src=''/></div></div >);
var e2=document.getElementById("displayblog");
angular.element(e).append($div).injector().invoke(function($compile) {
var scope = angular.element($div).scope();
$compile($div)(scope);
});
angular.element(e2).append($div2).injector().invoke(function($compile) {
var scope = angular.element($div2).scope();
$compile($div2)(scope);
});
currentg1++;
};
file element is create dynamically after calling add function and also when i set the myservice.setFilePath its give error in newFile.val !!!
Okay, I don't have time to rewrite the code but here are a few things to look at:
1) In your service, I don't think filepath is ever defined and that's probably why you're getting the error.
2) I don't think this syntax will work:
filepath[name][index]
Maybe you intended to use dot notation, like this:
filepath.name[index]
3) In your controller, you have a string that isn't closed which is causing the rest of the code in the controller to be interpreted as a string.
4) Instead of all of those HTML strings in the controller, check out angular's data binding capabilities. You should be able to create all those HTML elements in your template and use angular directives or data binding to make the templat dynamic. For example:
<div>
<label id='desccodeL{{currentg1}}'for='desccodeL{{currentg1}}'>
Code {{currentg1}}
</label>
</div>