In multiple image upload how to delete particular image if i click that image in angularjs.i have uploaded multiple image and i have textbox with every uploaded image.if i click image delete icon it removes the image with that textbox.my view code looks below
<input type="file" multiple file-upload /> {{files.length}}
<div ng-repeat="step in files">
<img ng-src="{{step.src}}" />
<input type="text" ng-model="comment[$index]"><br>
<input type="button" onclick="removeImage($index)" value="delete">
</div>
In my angular controller code looks like below
app.directive('fileUpload', function() {
return {
scope: true, //create a new scope
link: function(scope, el, attrs) {
el.bind('change', function(event) {
var files = event.target.files;
//iterate files since 'multiple' may be specified on the element
for (var i = 0; i < files.length; i++) {
//emit event upward
scope.$emit("fileSelected", {
file: files[i]
});
}
});
}
};
});
$scope.files = [];
$scope.$on("fileSelected", function(event, args) {
var item = args;
$scope.files.push(item);
var reader = new FileReader();
reader.addEventListener("load", function() {
$scope.$apply(function() {
item.src = reader.result;
});
}, false);
if (item.file) {
reader.readAsDataURL(item.file);
}
});
Instead of onclick use ng-click and use javascript splice function to remove an item from an array
<input type="button" ng-click="removeImage($index)" value="delete">
$scope.removeImage = function(index){
$scope.files.splice(index,1)
}
Related
I am trying to upload image and previewing it one by one but it replace last image.
I want to keep adding up more and more images but only last image is showing in received $_FILES array
Keep all upload images in form and keep them previewing.
my code
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="index.php" method="post" enctype="multipart/form-data">
<input type="file" id="add-gallary" name="filecollections[]">
<input type="submit" value="Submit">
<div class="gallery"></div>
</form>
<script>
$(function() {
var upload_count = 0;
var imagesPreview = function(input, placeToInsertImagePreview) {
if (input.files) {
var filesAmount = input.files.length;
for (i = 0; i < filesAmount; i++) {
var reader = new FileReader();
reader.onload = function(event) {
$($.parseHTML('<img>')).attr('src', event.target.result).appendTo(placeToInsertImagePreview);
}
// input.files.append(input.files[i]);
reader.readAsDataURL(input.files[i]);
upload_count++;
}
}
};
$('#add-gallary').on('change', function() {
imagesPreview(this, 'div.gallery');
});
});
</script>
The reason why only last images is getting uploaded is that you are storing the images in an array because you have single file upload input.
If you want upload multiple images you have previewer on form submit you would need to store them in array i have named imagesToUpload
Once you have all the images previwed and ready to submit the form with images you have selected and previewed you have loop forEach through that array imagesToUpload and append those file data to formData.
You will then this formData to your backend and upload all the images on backend using ajax request.
Run snippet below to see that array is using .push function to store all your images you have previewed.
$(function() {
var upload_count = 0;
//Store images in array
var imagesToUpload = []
var imagesPreview = function(input, placeToInsertImagePreview) {
if (input.files) {
var filesAmount = input.files.length;
for (i = 0; i < filesAmount; i++) {
var reader = new FileReader();
reader.onload = function(event) {
$($.parseHTML('<img>')).attr('src', event.target.result).appendTo(placeToInsertImagePreview);
}
// input.files.append(input.files[i]);
//Push images to array on preview
imagesToUpload.push(input.files[i])
reader.readAsDataURL(input.files[i]);
upload_count++;
}
}
};
$('#add-gallary').on('change', function() {
imagesPreview(this, 'div.gallery');
console.log(imagesToUpload)
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="index.php" method="post" enctype="multipart/form-data">
<input type="file" id="add-gallary" name="filecollections[]">
<input type="submit" value="Submit">
<div class="gallery"></div>
</form>
I am very new to front-end development and I thought it would be cool to add drag and drop to a current upload page. However after starting to hook everything up with ng-flow (a directive that assists with drag and drop) I cannot seem to make the connection on how to add the files to the file list. If you think I don't even need the directive and am just overkilling this and there is a simpler solution I would be willing to make changes as well. NOTE: I am giving only samples of the code so dont ding it for not compiling!
fileModelDirective:
app.directive('fileModel', ['$parse', '$log', '$confirm',
function ($parse, $log, $confirm) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
scope.sampleFile = model;
element.bind('change', function () {
// if the file open dialog is raised and the file name
// is cleared and cancel is pressed then a reset is needed
// document.getElementById('file-upload-name').innerHTML = "";
// document.getElementById('file-upload-btn').disabled = true;
// status always needs reset if choosing another file
scope.$apply(function () {
modelSetter(scope, element[0].files);
if (document.getElementById('file-upload').files) {
// This iterates over to see if the total files size is greater than 100MB
const maxFilesSize = 104857600;
var totalFilesSize = 0;
var numberOfDataSamples = element[0].files.length;
}
});
});
} // link
};
}]); // fileModel
fileMethod
$scope.uploadFile = function () {
console.log(flow)
var file = flow.file;
$scope.numberOfFiles = document.getElementById('file-upload').files.length;
$scope.filesTotalSize = 0;
for (var i = 0; i < document.getElementById('file-upload').files.length; i++) {
$scope.filesTotalSize = document.getElementById('file-upload').files[i].size + $scope.filesTotalSize;
}
fileUpload Service
app.service('fileUpload', ['$http', '$log',
function ($http, $log) {
this.uploadFileToUrl = function (file, uploadUrl) {
//$log.debug("file(s)");
//$log.debug(file);
var fd = new FormData();
angular.forEach(file, function (value, key) {
fd.append(key, value);
});
return $http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {
'Content-Type': undefined,
'enctype': "multipart/form-data"
}
})
}; // uploadFileToUrl
}]); // fileUpload
html
<div flow-init flow-files-submitted="$flow.upload()" class="ng-scope">
<div flow-drop>
<span for="file-upload"
class="btn btn-primary" flow-btn style="margin-top: 10px; ">Upload File
<input id="file-upload" type="file" multiple="multiple" file-model="sampleFile"
style="visibility: hidden; position: absolute;"></span>
<p flow-prevent-drop
flow-drag-enter="style={border: '5px dashed purple'}"
flow-drag-leave="style={}"
ng-style="style"
style="margin-top: 10px;width: 100%;min-height: 50px;">
Drag And Drop your file here</p>
<br>
<span ng-repeat="file in $flow.files track by $index">
{{file.name + ", " }}
</span>
<div style="margin-left: 2px; margin-top: 10px;">
<button id="file-upload-btn" class="btn btn-primary"
ng-click="showMask(); uploadFile();">
Upload
</button>
<button class="btn btn-primary" style="float: right;"
ng-click="navigateTo('/startup')">
Cancel
</button>
<button style="float: right; margin-right: 6px;" class="btn btn-primary"
ng-click="$flow.cancel()">
Clear
</button>
</div>
</div>
</div>
I'm just experimenting with a similar service. Taking angular Array of files, and pushing the items onto the javascript "file-upload".FileList array, but no luck, as the 'files' property is a readonly FileList object.
A pre-packaged solution:
http://blueimp.github.io/jQuery-File-Upload/angularjs.html
and it has drag and drop on to the whole page working.
This one: http://angular-file-upload.appspot.com/ even has Paste and access to Camera on mobile.
Your solution for adding files to the formData is good and inline with jquery ajaxSubmit form code
Maybe you could create a Plnk to collaborate on ...
formdata.append(a[i].name, a[i].value);
I've created a CodePen example of my problem.
I'm using the HTML5 FileReader and Angular to create a simple multi-file upload with a preview of the images that are to be uploaded.
The problem:
I am not getting the selected images in the ng-repeat span. I do however get the correct image data when I log it out to the console... what am I doing wrong?
HTML:
<div class="container" ng-app="my.app" ng-controller="FileUploadController">
<div class="row">
<div class="page-header">
<h3>File Upload Test</h3>
</div>
<input type="file" class="well" id="files" name="files[]" multiple onchange="angular.element(this).scope().upload()" />
<span ng-repeat="x in images">
<img ng-src="{{x}}" />
</span>
</div>
</div>
CSS:
img {
max-height: 100px;
}
Javascript:
var app = angular.module("my.app", []);
app.controller("FileUploadController", function($scope) {
$scope.images = [];
$scope.upload = function() {
var files = document.getElementById("files").files;
if (files) {
for (i = 0; i < files.length; i++) {
if (files[i]) {
var reader = new FileReader();
reader.onload = function (e) {
console.log(e.target.result);
$scope.images.push(e.target.result);
}
reader.readAsDataURL(files[i]);
}
}
}
};
})
http://jsfiddle.net/orion514/kkhxsgLu/136/ has the same working implementation.
<div ng-repeat="x in images">
<img class="thumb" ng-src="{{x}}" />
$scope.images = [];
$scope.imageUpload = function(event){
var files = event.target.files; //FileList object
for (var i = 0; i < files.length; i++) {
var file = files[i];
var reader = new FileReader();
reader.onload = $scope.imageIsLoaded;
reader.readAsDataURL(file);
}
$scope.imageIsLoaded = function(e){
$scope.$apply(function() {
$scope.images.push(e.target.result);
});
}
}
try $scope.$apply() when you modify collection like below,
reader.onload = function (e) {
console.log(e.target.result);
$scope.images.push(e.target.result);
$scope.$apply();
}
I want to upload multiple files and want to show their progress.I am trying the following code.
Here is my html code...
<div id='albumBox'>
<input type='file' multiple name='newsfeedAlbum[]' id='newsfeedAlbum' onchange='uploadNewsfeedImages()' />
<div>
<div id='uploadingImages'>
</div>
<div>
<preogress id='progressBar'> </progress>
</div>
<div>
<input type='button' id='albumButton' value='post' disabled />
</div>
here is my javascript code...
function uploadNewsfeedImages()
{
alert(document.getElementById("newsfeedAlbum").files.length);
var files = document.getElementById("newsfeedAlbum").files;
for(var i = 0;i < files.length;i++)
{
var file = files[i];
//alert("file name is "+files.item(i).name);
var formData = new FormData();
formData.append("image",file);
var xhr = new XMLHttpRequest();
xhr.open("POST","add_newsfeed.php",true);
alert(i);
xhr.upload.onprogress = function()
{
alert("bujji" + i);
}
xhr.send(formData);
}
}
function showUploadProgress(event)
{
var uploaded = event.loaded/event.total;
uploaded = Math.floor(uploaded*100);
document.getElementById("progressBar").value = uploaded;
}
But when I am trying to upload two images and alerting on upload.progress event it is alerting bujji2 and bujji2 instead of bujji0 and bujji1.How to handle individual upload.progress events....
It's a scope issue. The for loop will have completed by the time the onprogress events will trigger, so 'i' will be 2 every time the onprogress triggers because your 'for-loop' has finished running.
You can wrap the onprogress function in a closure to get the desired effect.
xhr.upload.onprogress = (function() {
return function() {
alert('bujji' + i);
};
}());
You need to save your i, because it will be changed before onprogress fired.
xhr.upload.fileNum = i;
xhr.upload.onprogress = function()
{
alert("bujji" + this.fileNum);
}
xhr.send(formData);
And read explanation for previous answer: Creating_closures_in_loops.3A_A_common_mistake
I have div which was dropzone to drop file(s) in the div,
<div id="dropZone"></div>
<input type="file" id=fileUpload"/>
I want to bind drop files to the html file type "fileUpload" control. I have tried like
but not getting. is it possible?
I have written the script for the div
$('#dropZone').bind('dragenter', ignoreDrag);
$('#dropZone').bind('dragover', ignoreDrag);
$('#dropZone').bind('drop', function (e) {
drop(e);
});
Edited and Added script
//Updated
function ignoreDrag(e) {
e.originalEvent.stopPropagation();
e.originalEvent.preventDefault();
}
//Updated End
and in the drop function
function drop(e) {
ignoreDrag(e);
var dt = e.originalEvent.dataTransfer;
var droppedFiles = dt.files;
if (dt.files.length > 0) {
for (var i = 0; i < dt.files.length; i++) {
var fileName = droppedFiles[0].name;
$("#lblMsg").show();
$("#spnFile").text(fileName);
var formData = new FormData();
formData.append("fileUploaded", droppedFiles);
alert(dt.files[0]);
$("#fileUploaded").bind("val", dt.files[0]);
// Binding to file(s) to the <input type="file"/> but not binding.
}
}
}
Is this possible to bind like above??