Id like to implement a UI where the user selects an image and that image is instantly displayed back to them for review. The user would have to click "submit" to upload/save the image to their profile.
I am having issues with the "instantly display back to the user part".
I am using angular FormData with the following markup & controller:
MARKUP
<input id="chooseFile" type="file" file-model="picFile" />
<img src="{{uploadedImage}}" /> <!-- this populates with filename but what is the path?? -->
CONTROLLER
angular.element('#chooseFile').change(function(){
var file = $scope.picFile; // this comes up "undefined" since file is still uploading when this is fired
$scope.uploadedImage = file.name;
});
I have 2 primary issues with the above code (described in comments):
1) In the controller, file comes up undefined obviously because even the smallest file takes >0s to upload while the callback is fired pretty much instantaneously. I got it work using $timeout but thats a bit of a lame hack. How can I have the callback wait until the file is uploaded??
2) The idea is to upload the file and display it in the img tag using Angular's data-binding. This works in that src is populated with the filename, but what is the path of the img. Some temporary location in cache or something?? Obviously I havent set a path to move the file yet.
Any help appreciated!
I also needed this feature, some how I manage to display image instantly.
angular.module('HelloWorldApp', [])
.controller('HelloWorldController', function($scope) {
$scope.uploadavtar = function(files) {
//var fd = new FormData();
//Take the first selected file
//fd.append("file", files[0]);
var imagefile = document.querySelector('#file');
if (imagefile.files && imagefile.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#temp_image')
.attr('src', e.target.result);
};
reader.readAsDataURL(imagefile.files[0]);
this.imagefile = imagefile.files[0];
}else{
console.log("Image not selected");
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="HelloWorldApp">
<div ng-controller="HelloWorldController">
<input type="file" id="file" onchange="angular.element(this).scope().uploadavtar(this.files)"/>
</div>
<img src="" id="temp_image" width="100">
<div>
</div>
</div>
I was using laravel + Angularjs so another related post to store image is : https://stackoverflow.com/a/34830307/2815635
Related
I am making angular application with image upload option which has the,
Html :
<label class="hoverable" for="fileInput">
<img [src]="url ? url : avatarImage">
<div class="hover-text">Choose file</div>
<div class="background"></div>
</label>
<br/>
<input id="fileInput" type='file' (change)="onSelectFile($event)">
<button *ngIf="url" (click)="delete()" >delete</button>
<img (click)="uploadPersonaImage($event)" class="avatar-images" src="https://www.w3schools.com/howto/img_avatar.png">
<img (click)="uploadPersonaImage($event)" class="avatar-images" src="https://www.w3schools.com/howto/img_avatar2.png">
Here what i am having is if the user clicks over the image he can select and update whatever image he has in local.
Same way if the user was not interested to update the profile image but interested to select any of the avatar image as per his/her wish which i have given like,
<img (click)="uploadPersonaImage($event)" class="avatar-images" src="https://www.w3schools.com/howto/img_avatar.png">
<img (click)="uploadPersonaImage($event)" class="avatar-images" src="https://www.w3schools.com/howto/img_avatar2.png">
And in ts made something like this,
uploadPersonaImage(e) {
this.url = e.target.src;
}
So on the click function the src that comes from the event.target was set to this.url..
But i need to convert it as file.. Because i need to send it as file to the service call so i need to update the avatar image.
So please help me to convert the avatar image selected/clicked by the user to the file/formdata so that it can be sent to the service as file format and can be updated as user selected image..
Example: https://stackblitz.com/edit/angular-file-upload-preview-85v9bg
You can use FormData to attach the read file and send to the API.
onSelectFile(event) {
if (event.target.files && event.target.files[0]) {
this.uploadToServer(event.target.files[0]);
... rest of the code
}
uploadToServer(file) {
let formData: FormData = new FormData();
formData.append('fileName', file);
// call your api service to send it to server, send formData
}
EDIT:
Try this out if you have no option to touch onSelectFile() or trigger a different function when you upload the file.
_url = ''
set url(val) {
this._url = val;
if (val) {
this.dataURLtoFile(val);
}
}
get url() {
return this._url;
}
uploadedImage: File ;
dataURLtoFile(dataurl) {
const arr = dataurl.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const imageExtension = mime.split('/')[1];
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
this.uploadedImage = new File([u8arr], `uploaded.${imageExtension}`);
}
On your API call, maybe when you click on a button,
uploadPersonaImage(e) {
// this.apiService.someMethod(this.uploadedImage);
}
If you want to trigger the API call just when you upload the image, add the code of dataURLtoFile() to uploadPersonaImage() and call uploadPersonaImage() from url setter
Clarification
Do you understand what does event.target.src mean (considering e as event)?
Here event means the click/change event you triggered when you
clicked onto upload photo.
event.target means the DOM element on which the event took place.
event.target.src will give you the src attribute value of the
DOM element on which you triggered the change event.
Now, you say won't it work? No, it won't because the element which you clicked is an HTMLInputElement but the src resides under the image in under the label tag. And how are you intending to call uploadPersonaImage()? what calls your method? You haven't answered that even after asking so many times.
In my last edit, I have added code under the setter of the url which will convert the dataUrlFile to an actual File, It completely depends on your server how you want to store the file. As a file or as a dataUrl? If you want to send it as a file then follow the conversions I added in the answer if you want to save as dataUrl then directly save the content of this.url on your API call.
I want to take input values from user like name, address, phone. After entering values I want to generate a doc (ms word doc file), make it available to be downloaded locally on click on button using angularjs. How can I achieve this?
Is it possible at client side or it should be from server side?
<input type='text' ng-model='user.username'/>
<input type='number' ng-model='user.phone'/>
<a href='someX.doc' download>download</a>
in my controller, I want to generate doc file, download it on click of link (download).
This will work
In your HTML add the following Line
<a download='someX.doc' ng-click="downloadMyDoc()" ng-href="{{ url }}" style="cursor: pointer">Download</a>
In your angular file add the following
var app=angular.module("myApp",[]);
app.config(['$compileProvider',
function ($compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|blob):/);
}]);
app.controller("homeCtrl",function($scope){
$scope.user={};
$scope.downloadMyDoc=function(){
alert("a");
var user=$scope.user;
var content = 'Username: '+user.username+'phone: '+user.phone;
var blob = new Blob([ content ], { type : 'text/plain' });
$scope.url = (window.URL || window.webkitURL).createObjectURL( blob );
}
});
For context, I'm trying to create a "click image" file uploader. Initially there is a default image, which I then click. I trigger a file upload, and the user picks an image file they want. Then I will set the image to replace the default (and do other things with it later). Right now, the front end looks something like this:
<div class="right-preview">
<input type="image" src="img/logo.png" height="240px" width="240px" ng-click="uploadImage('right-image')" id="upload-right-image"/>
<input type="file" id="upload-right" style="visibility: hidden">
</div>
When the image is clicked, it triggers an upload action.
$scope.uploadImage = function(side) {
$image = $('#upload-' + side);
$fileInput = $('#upload-right');
$fileInput.change(function(changeEvent) {
var files = changeEvent.target.files;
for(var i = 0; i < files.length; i++) {
file = files[i];
console.log(file);
}
});
$fileInput.trigger('click');
}
When the change event is fired after the user finishes picking their file, I have the changeEvent and I know they've selected their file. Each of the files has some properties (like name and size) but I'm not seeing anything for accessing the raw data so I can set the src on my other element.
Am I just completely missing how to get the image data, or is there a better way to do this? I have no server (right now) to post this to. Perhaps there is a better way to approach this?
This link may be helpful to you - https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL
I took one method from that page and added some additional functionality to hide the file upload button and have the image placeholder trigger its click event.
$('#placeholder').click(function() {
$('#img-upload').trigger('click');
});
function previewFile() {
var preview = document.querySelector('img');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener("load", function () {
preview.src = reader.result;
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<img width="250" height="250" id="placeholder" src="http://place-hold.it/250x250&text='click to upload'">
<input class="hidden" type="file" onchange="previewFile()" id="img-upload">
I have a JavaScript image uploader which will upload an image and give me the image src. I need to save this value in my FireBase DB for the current user being created.
I tried outputting the img.src to a hidden input but that didn't seem to work. Like so:
$('.userImageValue').val(img.src);
<input class="userImageValue" ng-model="data.userImage" style="display: none;">
I just figured out if I change the value once it is added to the invisible input it works. So how can I best make the input "register" after the src value is inserted?
Here is the controller where a new user is created.
$scope.list = $firebaseArray(new Firebase("https://my-db.firebaseio.com/users"));
// Create user button
$scope.add_new_user = function() {
console.log($scope.data);
$scope.list.$add($scope.data);
$scope.data = {};
}
This is an input on the page which currently works with the above code and saves a new field for the current user being created.
<input id="firstname" type="text" ng-model="data.firstname" class="form-control" placeholder="First name">
This is the part I am stuck on I need to save the value of img.src from the code below as a new field in the FireBase DB for the user currently being created.
var userImageUploader = document.getElementById('userImageUploader');
userImageUploader.addEventListener('change', function(e) {
var file = userImageUploader.files[0];
var imageType = /image.*/;
if (file.type.match(imageType)) {
var reader = new FileReader();
reader.onload = function(e) {
var img = new Image();
img.src = reader.result;
}
reader.readAsDataURL(file);
}
});
I hope that makes sense and thank you in advanced!
You may want to consider using Parse for the image portion.
1) it also has a free tier but with much larger storage than the firebase free tier, which will quickly be exhausted by images.
2) it has better tools for images imo.
I need to send selected image to the server, here is already I have tried
here is HTML part
<div class="row">
<input type="file" name="filUpload" id="filUpload" onchange="showimagepreview(this)">
<br />
<img id="imgprvw" alt="uploaded image preview" class="img-thumbnail" />
</div>
I need to get encoded image into javascript variable,But I have no idea
for uploading image on to server you need to send image data via AJAX to server side.
for reference you can see this link :
http://www.sanwebe.com/2012/05/ajax-image-upload-and-resize-with-jquery-and-php
http://phppot.com/php/php-ajax-image-upload/
you can try using jquery's base64 plugin. Jquery.Base64 plugin
and do it like this:
function showimagepreview(c) {
var file = c;
if(file.files.length)
{
var reader = new FileReader();
reader.onload = function(e)
{
var b = $.base64.encode(e.target.result);
$("#imgprvw").attr("src", "data:image/png;base64," + b);
};
reader.readAsBinaryString(file.files[0]);
}
}