How do I change the list of uploaded files? - javascript

I am attempting to use XMLHttpRequest to upload files to the server. Here are the steps I would like the code to do:
List the file in a file list ul
Upload the file(s) while displaying a progress bar
When the file is completely uploaded, change the list item for that file to a link without the progress bar. This is where I am having a problem.
Here is the HTML code I am working with:
<h1>Upload Files</h1>
<input type='file' name='doc_upload_field[][]' multiple='multiple' id='doc_upload_field' />
<ul id='filelist'></ul>
Here is the javascript code I am working with:
function transferFailed(evt) {
alert("An error occurred while transferring the file.");
}
function transferCanceled(evt) {
alert("The transfer has been canceled by the user.");
}
var filelist = $('#filelist');//define where the list of files will go
var url = "/";
function handleFileSelect_inputfield(evt) {
var files = evt.target.files; // FileList object
// run through each file individually.
for (var i = 0, f; f = files[i]; i++) {
var li = $("<li><strong>" + f.name + "</strong> (" + f.type +") - " + f.size + " bytes <div class='progress_bar'><div class='percent'> </div></div></li>");
filelist.append(li);//put the file in the filelist
var formData = new FormData();
formData.append(f.name, f);
//upload through xmlhttprequest
var xhr = new XMLHttpRequest();
xhr.upload.li = li;
xhr.upload.addEventListener("progress", function(e) {
if (e.lengthComputable) {
var percentLoaded = Math.round((e.loaded / e.total) * 100);
// Increase the progress bar length.
if (percentLoaded < 100) {
this.li.find(".progress_bar").addClass('loading');
this.li.find(".percent").width(percentLoaded + '%');
}
}
}, false);
xhr.upload.addEventListener("load", function(e) {
//uploading is complete
}, false);
xhr.upload.addEventListener("error", transferFailed, false);
xhr.upload.addEventListener("abort", transferCanceled, false);
xhr.open('POST', url, true);
xhr.responseType = 'text';
xhr.onload = function(e) {
if (this.readyState==4){
if (this.status == 200) {
//console.log(this.response);
console.log("finished=" + li);//returns as an object
//console.log("filename=" + f.name);//error: cannot read property 'name' of undefined
//change the list item. Not working...
this.li.find("li").html("<a href='#'>" + f.name + "</a>");
}
}
};
xhr.send(formData); // multipart/form-data
}
}
document.getElementById('doc_upload_field').addEventListener('change', handleFileSelect_inputfield, false);
Everything seems to be working, but when I want to change the list item, li, it is not recognizing it. I am able to change the progress bar length by calling:
this.li.find(".progress_bar").addClass('loading');
this.li.find(".percent").width(percentLoaded + '%');
But when I want to change the list item:
this.li.find("li").html("<a href='#'>" + f.name + "</a>");
It does not work.
Does anyone know why it would find it when changing the progress bar, but not find it after it is uploaded?

The expression
this.li.find("li")
looks for an <li> element inside the other <li> element. There isn't one, so nothing happens.
I think that just
this.li.html("<a href='#'>" + f.name + "</a>");
should be what you want. Or you could just do this:
this.li = $("<li><a href='#'>" + f.name + "</a></li>");
edit oops no that won't work because you've stuck it in the DOM already. But the first one should work.
edit — you've also got a closure-related problem (or scope-related; whatever). What you can do is something like what you've already done for the "li" value. Add another property for it to "xhr.upload":
xhr.upload.updated_li = "<a href='#'>" + f.name + "</a>";
Do that right where you set "xhr.updated.li". Then, in the event handler, you can do:
this.li.html(this.updated_li);

Related

Limit the number of uploads in plupload

My client is using an old classipress version, here's a github repo I found but what he's using is much older. Running the latest Wordpress version. It comes with plupload, some old version, couldn't find the version in the theme. Here's Functions.php, here's plupload. Here's the html of my page, no need to see it, but i'm putting it there because the page is protected so that's the only way to inspect the whole code if you want to.
I want to add the ability to upload multiple pictures at the same time, to do that, I add this to functions.php
add_filter('appthemes_plupload_config', 'enable_plupload_multisel', 10 ,1);
function enable_plupload_multisel($app_plupload_config){
$app_plupload_config['plupload']['multi_selection'] = true;
return $app_plupload_config; }
But I don't know how to stop the user from uploading more than 8 pictures? I tried adding max_files and max_files_count and max_file_count and nothing worked, I even modified the source code of the plugin itself and the js and nothing worked. I want to stop the user from being able to upload more than 8 images.
After I gave up on plupload, I tried doing it using Jquery, again didn't work
/* prevent form submission if user selects more than 8 pics */
jQuery('#app-attachment-upload-pickfiles').change(function() {
if (this.files.length > 8) {
alert('Uploading more than 8 images is not allowed');
this.value = '';
}
});
// Prevent submission if limit is exceeded.
jQuery('#mainform').submit(function() {
if (this.files.length > 8) {
jQuery('#app-attachment-upload-pickfiles').hide();
jQuery('#step1').hide();
return false;
} else {
jQuery('#app-attachment-upload-pickfiles').show();
jQuery('#step1').show();
}
});
Edit
My pluploadjs here. FilesAdded
attachUploader.bind('FilesAdded', function(up, files) {
jQuery.each(files, function(i, file) {
jQuery('#app-attachment-upload-filelist').append(
'<div id="' + file.id + '" class="app-attachment-upload-progress">' +
file.name + ' (' + plupload.formatSize(file.size) + ') <b></b>' +
'</div>');
window.appFileCount += 1;
APP_Attachment.hideUploadBtn();
});
up.refresh();
attachUploader.start();
});
I modified it to look like so
attachUploader.bind('FilesAdded', function(up, files) {
var maxfiles = 8;
if(up.files.length > maxfiles )
{
up.splice(maxfiles);
alert('no more than '+maxfiles + ' file(s)');
}
if (up.files.length === maxfiles) {
$('#app-attachment-upload-filelist').hide("slow"); // provided there is only one #uploader_browse on page
}
jQuery.each(files, function(i, file) {
jQuery('#app-attachment-upload-filelist').append(
'<div id="' + file.id + '" class="app-attachment-upload-progress">' +
file.name + ' (' + plupload.formatSize(file.size) + ') <b></b>' +
'</div>');
window.appFileCount += 1;
APP_Attachment.hideUploadBtn();
});
up.refresh();
attachUploader.start();
});
Is that all? Will it work now? I haven't tested it because it will give errors
I'm not sure but your code should almost work. I think you should manually remove the files from the queue by calling the removeFile method.
Maybe try this code:
attachUploader.bind('FilesAdded', function(up, files) {
var maxfiles = 8;
// remove all new files after the max of files
jQuery.each(up.files, function(i, file) {
if(i > maxfiles){
up.removeFile(file);
}
});
});

How can I do update with using same id but different content?

Currently, I working on form that got an input for image file. After browse image then upload it I will get the id for the image. Here is my code for POST.
$("#smallpicture_id").change(function () {
displayAndShowImage(this,'#smallimg','#smallimg');
});
$("#largepicture_id").change(function () {
displayAndShowImage(this,'#largeimg','#largeimg');
});
function displayAndShowImage(input,targetHtmlElementName) {
if (input.files && input.files[0]) {
var files = input.files;
var reader = new FileReader();
reader.onload = function (e) {
$(targetHtmlElementName).attr('src', 'images/uploading.gif');
var formData = new FormData();
formData.append('userfile',files[0],files[0].name);
createImage(
config,
formData,
{
onSuccess : function(data) {
$(targetHtmlElementName).attr('src', e.target.result);
$.cookie(input.id, data);
console.log("Image has been save - Received ID: " + data + " saved in the cookie " + input.id);
},
onError : function(jqXHR, status) {
$(targetHtmlElementName).attr('src', 'images/img-error.png');
console.log("ERROR " + jqXHR.responseText + "\r\nstatus = " + status);
}
}
);
}
reader.readAsDataURL(files[0]);
}
}
Ajax
function createImage(cfg,formData,callbacks) {
var xhr = new XMLHttpRequest();
xhr.open('POST', cfg.url + "/image/", true);
xhr.onload = function () {
if (xhr.status === 200) {
// File(s) uploaded.
callbacks.onSuccess(xhr.responseText.trim());
} else {
callbacks.onError(xhr);
}
};
xhr.send(formData);
}
My question is how can I update / delete for my image with using the same id that given to the image. I already can do POST and GET but I still don't get any idea how to update and delete.
You can append two string in FormData query identifier and ID (only in case of update & delete), like
formData.append('queryType', 'DELETE')
formData.append('imageID', input.id)
On server side code (where you have added code for saving new Image) you have to add condintion like this
<?php
$identifier=$_POST['queryType'];
if($identifier=="NEW") {
//save file with new ID and return ID
} elseif ($identifier=="UPDATE")
//update Image Data ($_FILE) with ID appended in formdata
} elseif ($identifier=="DELETE")
//Delete existing image at ID specified
}
?>
hope this may help.
You can give your elements specific classname for each upload process, which have same id, then run displayAndShowImage function for only elements has "update-this" classname.
$("#smallpicture_id").change(function () {
$(this).addClass("update-this"); // add update-this class
$(".update-this").not($(this)).removeClass("update-this"); // remove all update-this classnames from all other ones
// then run your function for only element which has update-this classname
displayAndShowImage(this,'.update-this');
});

looking to Work around the 403 error with php script

I have been using JavaScript to retrieve my images from a directory and on local-host this works just fine but now I am running it on a remote sever I get the 403 Forbidden Error, I know why this is but I am looking for a way around it, keeping my Java functioning much the same, so I was thinking if I put an index.php in the gallery folder and called it with a path and have it return a file list back to my JavaScript and a lough it to carry on.
How would I go about this as I am not very good with PHP at the moment? Thanks.
<script type="text/javascript">
$(document).ready(function() {
$("a").click(function() {
var dir_path = $(this).data("albumid");
LoadGallery(dir_path);
return false;
});
});
function LoadGallery(dir_path) {
$.ajax({
url: dir_path,
success: function(data) {
$(".image-container").empty();
$(data).find("a:contains(.jpg), a:contains(.png), a:contains(.jpeg)").each(function() {
this.href.replace(window.location.host, "").replace("http:///", "");
var file = dir_path + $(this).text();
$(".image-container").append($("<a href='javascript:;' class='thumb' data-src='" + file + "'><img src='" + file + "' title='Click to enlarge' alt='#'/></a>"));
if ($(".image-container").children("a").length === 30) {
return false;
}
});
$(".image-container").append("<strong><p>Click on a thumb nail to show a larger image.</p></strong>");
$(".thumb").bind('click', function() {
var Popup = "<div class='bg'></div>" + "<div class='wrapper'><img src='<img src=''/>" + "<label href='javascript:;' class='prev-image'>«</label><label href='javascript:;' class='next-image'>»</label><a href='javascript:;' class='close' title='Close'>Close</a>";
var Img = $(this).attr("data-src");
$("body").prepend(Popup);
$(".bg").height($(window).height() * 4);
$(".wrapper img").attr("src", Img);
$(".prev-image").bind('click', function() {
var prev = $(".image-container").find("img[src='" + Img + "']").parent().prev('a').find("img").attr('src');
if (!prev || prev.length === 0)
return false;
else {
$(".wrapper img").attr("src", prev);
Img = prev;
}
});
$(".next-image").bind('click', function() {
var next = $(".image-container").find("img[src='" + Img + "']").parent().next('a').find("img").attr('src');
if (!next || next.length === 0)
return false;
else {
$(".wrapper img").attr("src", next);
Img = next;
}
});
$(".close").bind('click', function() {
$(this).siblings("img").attr("src", "")
.closest(".wrapper").remove();
$(".bg").remove();
});
});
}
});
}
</script>
Original why are you getting the 403 error? returning a file(name) list from php to your scripts probably isn't going to work around this error, because the javascript would ultimately be making the same request.
on the other hand if you know that you have access to the image files from the server-side there are a few things you could do, like return the binary value of the image (javascript can take this) or generating a close of the file.
Update
if the server allows it, you can use the exec command in php to return a list of files from the directory: eg
\<\
<?php
jpgs = exec('ls /your_directory_here');
echo json_encode(jpgs);
?>
if they don't allow exec(), which they might not, you could try...
http://www.w3schools.com/php/func_directory_readdir.asp
does that help?

Get all images from local folder

I need a way to get all the images from a local folder for a presentation that will also run locally. There will be no attempt for a server to take the images from a local folder since that is not possible/the case.
I need to use .js since I can't use .php (which would be easier) since it runs on a local PC.
Say I need to take all the images from learn/
I have tried various solutions that can be found here, here and here but none worked.
I think your best option is to use the new File API in Javascript. Is has a lot of functions to read files from the file system.
<input type="file" id="fileinput" multiple />
<script type="text/javascript">
function readMultipleFiles(evt) {
//Retrieve all the files from the FileList object
var files = evt.target.files;
if (files) {
for (var i=0, f; f=files[i]; i++) {
var r = new FileReader();
r.onload = (function(f) {
return function(e) {
var contents = e.target.result;
alert( "Got the file.n"
+"name: " + f.name + "n"
+"type: " + f.type + "n"
+"size: " + f.size + " bytesn"
+ "starts with: " + contents.substr(1, contents.indexOf("n"))
);
};
})(f);
r.readAsText(f);
}
} else {
alert("Failed to load files");
}
}
document.getElementById('fileinput').addEventListener('change', readMultipleFiles, false);
</script>
(code from here)
You can find a good explanation and helpful code here.
Thanks to Patrick Hofman's answer, I modified the code and ended up with this :
$(document).ready(function(){
function readMultipleFiles(evt) {
//Retrieve all the files from the FileList object
var files = evt.target.files;
if (files) {
for (var i=0, f; f=files[i]; i++) {
var r = new FileReader();
r.onload = (function(f) {
return function(e) {
var contents = e.target.result;
$('body').append('<h1>' + f.name + '</h1><img src="learn/' + f.name + '"/>');
};
})(f);
r.readAsText(f);
}
} else {
alert("Failed to load files");
}
}
document.getElementById('fileinput').addEventListener('change', readMultipleFiles, false);
});

JS - File Reader API get image file size and dimensions

Hi i'm using the following code to get the upload image using File Reader API:
<script type="text/javascript">
var loadImageFile = (function () {
if (window.FileReader) {
var oPreviewImg = null, oFReader = new window.FileReader(),
rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;
oFReader.onload = function (oFREvent) {
/*get image*/
var _img = oFREvent.target.result;
console.log(oFREvent.target);
/*add img to hidden input text*/
localStorage.photo = _img;
oPreviewImg.src = oFREvent.target.result;
};
return function () {
var aFiles = document.getElementById("imageInput").files;
if (aFiles.length === 0) { return; }
if (!rFilter.test(aFiles[0].type)) {
notify("You must select a valid image file!",3400,false); return;
}
oFReader.readAsDataURL(aFiles[0]);
}
}
})();
</script>
<form name="uploadForm">
<p><input id="imageInput" type="file" name="myPhoto" onchange="loadImageFile();" /><br />
<input type="submit" value="Send" /></p>
<input type="hidden" id="photo_1_hidden" name="photo_1"/>
</form>
it works great and it returns the base64 data of the image.
now i would like to get also the image file size and the image width and height.
Is it possible?
I tryed to log in console the file but i can't find what i'm searching for.
Any help appriciated thanks so much!
Something like this?
var oPreviewImg = new Image();
oPreviewImg.onload = function(){
console.log(this.size);
alert("'" + this.name + "' is " + this.width + " by " + this.height + " pixels in size.");
return true;
};
oPreviewImg.onerror = function(){
alert("'" + this.name + "' failed to load.");
return true;
}
oPreviewImg.src = "//placeholdit.imgix.net/~text?txtsize=33&txt=350%C3%97150&w=350&h=150";
var xhr = new XMLHttpRequest();
xhr.open('HEAD', oPreviewImg.src, true);
xhr.onreadystatechange = function() {
console.log('this', this);
if ( xhr.readyState == 4 ) {
if ( xhr.status == 200 ) {
alert('Size in bytes: ' + xhr.getResponseHeader('Content-Length'));
} else {
alert('ERROR');
}
}
};
xhr.send(null);
Live version
Update Live version replaced with Fiddle, however, due to cross site scripting concerns, the size is no longer being retrieved effectively.
const reader = new FileReader()
reader.onload = (theFile) => {
const image = new Image()
image.src = theFile.target.result
image.onload = () => {
console.log('image width ===== ' + image.width + 'Image height
===== ' + image.height)
}
}
reader.readAsDataURL(item)
I don't believe that JS is going to be capable of getting that data without first rendering the image to the viewport. That is to say, I am unfamiliar of any method that would do what you ask in the JavaScript, or JQuery libraries. Your best bet for getting data like that is going to be rendering the image to the page in a preview capacity or using a more powerful language like PHP and using an Ajax request to get the data you're looking for.

Categories

Resources