How to get the image dimension with angular-file-upload - angularjs

I'm currently using the angular-file-upload directive, and I'm pretty much using the exact codes from the demo.
I need to add a step in there to test for the dimension of the image, and I am only currently able to do with via jQuery/javascript.
Just wondering if there's a "angular" way to check for the dimension of the image before it's being uploaded?
$scope.uploadImage = function($files) {
$scope.selectedFiles = [];
$scope.progress = [];
if ($scope.upload && $scope.upload.length > 0) {
for (var i = 0; i < $scope.upload.length; i++) {
if ($scope.upload[i] !== null) {
$scope.upload[i].abort();
}
}
}
$scope.upload = [];
$scope.uploadResult = [];
$scope.selectedFiles = $files;
$scope.dataUrls = [];
for ( var j = 0; j < $files.length; j++) {
var $file = $files[j];
if (/*$scope.fileReaderSupported && */$file.type.indexOf('image') > -1) {
var fileReader = new FileReader();
fileReader.readAsDataURL($files[j]);
var loadFile = function(fileReader, index) {
fileReader.onload = function(e) {
$timeout(function() {
$scope.dataUrls[index] = e.target.result;
//------Suggestions?-------//
$('#image-upload-landscape').on('load', function(){
console.log($(this).width());
});
//-------------------------//
});
};
}(fileReader, j);
}
$scope.progress[j] = -1;
if ($scope.uploadRightAway) {
$scope.start(j);
}
}
};

I think you can do it by:
var reader = new FileReader();
reader.onload = onLoadFile;
reader.readAsDataURL(filtItem._file);
function onLoadFile(event) {
var img = new Image();
img.src = event.target.result;
console.log(img.width, img.height)
}
This is the code snippet copied from https://github.com/nervgh/angular-file-upload/blob/master/examples/image-preview/directives.js.
I think this is more angularjs. However, you may need to modify it to fit your requirement.

Try this code
uploader.filters.push({
name: 'asyncFilter',
fn: function(item /*{File|FileLikeObject}*/ , options, deferred) {
setTimeout(deferred.resolve, 1e3);
var reader = new FileReader();
reader.onload = onLoadFile;
reader.readAsDataURL(item);
function onLoadFile(event) {
var img = new Image();
img.onload = function(scope) {
console.log(img.width,img.height);
}
img.src = event.target.result;
}
}
});

Related

How do i convert uploaded csv into json object in angularjs

var app = angular.module('myngCsv', [ngcsv]);
app.controller('ngcsvCtrl', function($scope,$csv) {
$scope.csv ={
content: null;
header: true,
headerVisible: true,
separator: ',',
separatorVisible: true,
result: null,
encoding: 'ISO-8859-1',
encodingVisible: true,
accept: ".csv"
};
});
This is what tried.
indeed.
You can write a function to convert CSV to JSON and pass your CSV object to it. All you need to do is to save the first row of CSV as headers (You can identify them by comma) and you can identify new entry by newline character \n
Go through the function I have written below.
function csvToJSON(csv, callback) {
var lines = csv.split("\n");
var result = [];
var headers = lines[0].split(",");
for (var i = 1; i < lines.length - 1; i++) {
var obj = {};
var currentline = lines[i].split(",");
for (var j = 0; j < headers.length; j++) {
obj[headers[j]] = currentline[j];
}
result.push(obj);
}
if (callback && (typeof callback === 'function')) {
return callback(result);
}
return result;
}
You can try using Papaparse looks very easy and elegant to use
Create fileReader directive:
<input type="file" data-file-reader-directive="fileContent" accept=".csv" />
Directive to get csv data from the file:
app.directive('fileReaderDirective', function() {
return {
restrict: "A",
scope: {
fileReaderDirective: "=",
},
link: function(scope, element) {
$(element).on('change', function(changeEvent) {
var files = changeEvent.target.files;
if (files.length) {
var r = new FileReader();
r.onload = function(e) {
var contents = e.target.result;
scope.$apply(function() {
scope.fileReaderDirective = contents;
});
};
r.readAsText(files[0]);
}
});
}
};
});
Create a factory to convert csv data to json data
app.factory('readFileData', function() {
return {
processData: function(csv_data) {
var record = csv_data.split(/\r\n|\n/);
var headers = record[0].split(',');
var lines = [];
var json = {};
for (var i = 0; i < record.length; i++) {
var data = record[i].split(',');
if (data.length == headers.length) {
var tarr = [];
for (var j = 0; j < headers.length; j++) {
tarr.push(data[j]);
}
lines.push(tarr);
}
}
for (var k = 0; k < lines.length; ++k){
json[k] = lines[k];
}
return json;
}
};
});
check out the working example : https://plnkr.co/edit/ml29G85knZpWWNdG8TeT?p=preview

How to access a method in one object from a second object

Hi I'm new to javascript. I have one object ListModel and I am trying to access the addToModel method from a second object.
function ListModel(){
this.list = {};
}
ListModel.prototype.addToModel = function(s){
var items = s.split("\n");
for( var i =0; i<items.length-1; i++){
console.log(items[i] + "\n");
}
}
After extensive searching I have been unable to find a solution to this problem.
The second object is:
function ListMaker(){
this.model = new ListModel();
}
ListMaker.prototype.read = function(e){
var f = e.target.files[0];
if (f) {
var r = new FileReader();
r.onload = function(e) {
var contents = e.target.result;
this.model.addToModel(contents);
document.getElementById("ta").innerHTML = contents;
}
r.readAsText(f);
} else {
alert("Failed to load file");
}
}
In the read method I call:
this.model.addToModel(contents);
and the console returns
Cannot read property 'addToModel' of undefined
If I change the line to:
this.model = new ListModel().addToModel(contents);
then the method works as excpected.
Maybe I'm going about this the wrong way.
Any help would be appreciated.
The problem is this
http://javascriptplayground.com/blog/2012/04/javascript-variable-scope-this/
Once you call a function, this is no longer pointing to what you think it is.
You need to stash this in a local and then reference the local in your callback.
ListMaker.prototype.read = function(e){
var f = e.target.files[0];
var _this = this;
if (f) {
var r = new FileReader();
r.onload = function(e) {
var contents = e.target.result;
_this.model.addToModel(contents);
document.getElementById("ta").innerHTML = contents;
}
r.readAsText(f);
} else {
alert("Failed to load file");
}
}
See it in action: http://codepen.io/anon/pen/eZrYQj

Angular JS range input issue

when the all corners range input is moved, the rest of the inputs work fine but when another corner range is moved the all corners move 1~3 pixels, what could be the issue here?
Demo here:
http://jsfiddle.net/g10fsxym/
code:
var myApp = angular.module('myApp', []);
myApp.controller('myAppCtrlr', function($scope) {
var allcorners = new Quantity(5);
var topLeft = new Quantity(5);
var topRight = new Quantity(5);
var bottomLeft = new Quantity(5);
var bottomRight = new Quantity(5);
$scope.brCorners = allcorners;
$scope.brTopLeft = topLeft;
$scope.brBottomLeft = bottomLeft;
$scope.brTopRight = topRight;
$scope.brBottomRight = bottomRight;
$scope.brTopLeftCorner = function() {
$scope.brTopLeft = topLeft;
}
$scope.brBottomLeftCorner = function() {
$scope.brBottomLeft = bottomLeft;
}
$scope.brTopRightCorner = function() {
$scope.brTopRight = topRight;
}
$scope.brBottomRightCorner = function() {
$scope.brBottomRight = bottomRight;
}
$scope.brAllCorners = function() {
$scope.brTopLeft = $scope.brCorners;
$scope.brTopRight = $scope.brCorners;
$scope.brBottomLeft = $scope.brCorners;
$scope.brBottomRight = $scope.brCorners;
}});
function Quantity(value) {
var qty = value;
this.__defineGetter__("qty", function() {
return qty;
});
this.__defineSetter__("qty", function(val) {
val = parseInt(val);
qty = val;
});}`
Just make a copy of $scope.brCorners (otherwise you are working with references, so when you change one variable the another is also changed).
Demo
$scope.brAllCorners = function() {
$scope.brTopLeft = angular.copy($scope.brCorners);
$scope.brTopRight = angular.copy($scope.brCorners);
$scope.brBottomLeft = angular.copy($scope.brCorners);
$scope.brBottomRight = angular.copy($scope.brCorners);
}

How testing file upload directive?

How can I test?
element.bind('change', function(evt) {
var files = evt.target.files;
if (!attrs.previewContainer) {
attrs.previewContainer = "preview";
var div = document.createElement("div");
var li = document.createElement("li");
li.appendChild(div);
li.id = attrs.previewContainer;
element.append(div);
}
if (typeof files !== "undefined") {
if (attrs.multiple) {
for (var i = 0, l = files.length; i < l; i++) {
loadMetadata(files[i], attrs).then(function(result) {
result.url = URL.createObjectURL(files[i]);
scope.metadata.push(result);
});
}
} else {
loadMetadata(files[0], attrs).then(function(result) {
result.url = URL.createObjectURL(files[0]);
scope.metadata = result;
});
}
}
});
The file HTML:
<input name='uploadVideo' type="file" metadata="uploadVideo"
preview-container="videoPreview" data-ng-model="uploadVideo.file">
I want to create a test file on a custom directive that deals in uploading a video and see a preview. So I would like to know how you create an event listening in angular:
Or similar
it('Test input file', inject(function() {
fakeFile = {
name: '/home/developer/mcd2/public/modules/uploads/store/videos/542e73cf054fbc3a1630d216/bear_movie.mp4'
};
var fileInput, evt;
fileInput = element.find('input').trigger('input');
evt = $.Event('change');
evt.target = {
files: [fakeFile]
};
angular.element(fileInput).triggerHandler(evt);
fileInput.trigger(evt);
expect(form.$modelValue.name).toBe(fakeFile.name);
expect(form.$valid).toBeTruthy();
}));

angular-file-upload with ngImgCrop

I'm using (ngImgCrop) to crop an image and then upload the cropped image to server using (angular-file-upload).
I can get the $dataURI from the "on-change" option in ngImgCrop. But I need a File instace to call $upload.
How can I get the File instance of the cropped image in order to upload :
$scope.upload = $upload.upload({
url: '/api/fileupload',
file: [**file cropped here**]
}).progress(function (evt) {
//
}).success(function (data, status, headers, config) {
//
});
I guess you'll find a proper answer in this method. I found it in Github, in the angular-file-upload issues page (https://github.com/nervgh/angular-file-upload/issues/208):
/**
* Converts data uri to Blob. Necessary for uploading.
* #see
* http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata
* #param {String} dataURI
* #return {Blob}
*/
var dataURItoBlob = function(dataURI) {
var binary = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {type: mimeString});
};
You should be able to get a file instance doing something like this:
var blob = dataURItoBlob($scope.croppedImage);
I don't know if it works in the good way, but it seems.
try something like:
var uploader = $scope.uploader = new FileUploader({
url: '/saveImagePath',
autoUpload: false
});
angular.element(document.querySelector('#fileInput')).on('change',handleFileSelect);
var handleFileSelect=function(evt) {
var file=evt.currentTarget.files[0];
var reader = new FileReader();
reader.onload = function (evt) {
$scope.$apply(function($scope){
$scope.myImage=evt.target.result;
});
};
reader.readAsDataURL(file);
};
the uploader doesn't support base64 images so you'll need to convert the cropped image from base64 to blob
function base64ToBlob(base64Data, contentType) {
contentType = contentType || '';
var sliceSize = 1024;
var byteCharacters = atob(base64Data);
var bytesLength = byteCharacters.length;
var slicesCount = Math.ceil(bytesLength / sliceSize);
var byteArrays = new Array(slicesCount);
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
var begin = sliceIndex * sliceSize;
var end = Math.min(begin + sliceSize, bytesLength);
var bytes = new Array(end - begin);
for (var offset = begin, i = 0 ; offset < end; ++i, ++offset) {
bytes[i] = byteCharacters[offset].charCodeAt(0);
}
byteArrays[sliceIndex] = new Uint8Array(bytes);
}
return new Blob(byteArrays, { type: contentType });
}
you have to manually attach the files to the queue like this:
$scope.submit = function () {
var file = base64ToBlob($scope.currentPortfolio.croppedImage.replace('data:image/png;base64,',''), 'image/jpeg');
uploader.addToQueue(file);
uploader.uploadAll();
};
in the server side, you got two types of files one posted as HTML file and another un base64 which is the cropped image.

Resources