Image preview send to php file via ajax - javascript

Having image preview option, that show the thumb of selected images.
Consider the below HTML,
html:
<input type="file" multiple accept="image/x-png,image/gif,image/jpeg" title="Upload Image" id="gallery_img" name="roomimage[]" />
Code used for previewing image in browser:
$(document).ready(function() {
if (window.File && window.FileList && window.FileReader) {
$("#gallery").on("change", function(e) {
var fileName = document.getElementById("gallery").value;
var idxDot = fileName.lastIndexOf(".") + 1;
var extFile = fileName.substr(idxDot, fileName.length).toLowerCase();
if (extFile=="jpg" || extFile=="jpeg" || extFile=="png"){
//TO DO
var files = e.target.files,
filesLength = files.length;
for (var i = 0; i < filesLength; i++) {
var f = files[i]
var fileReader = new FileReader();
fileReader.onload = (function(e) {
var file = e.target;
$("<span class=\"imgPreview\">" +
"<img id=\"image\" name=\"image[]\" class=\"imageThumb\" src=\"" + e.target.result + "\"/>" +
"<span class=\"remove icon-error\" title=\"Close\"></span>" +
"</span>").insertAfter(".gallery_section");
$(".remove").click(function(){
$(this).parent(".imgPreview").remove();
});
});
fileReader.readAsDataURL(f);
}
}else{
alert("Only jpg/jpeg and png files are allowed!");
}
});
} else {
alert("Your browser doesn't support to File API")
}
});
While choosing files with the above html all works fine. like i can select multiple images and i can upload that multiple images via ajax.
ajax:
var formData = new FormData($("#room_form")[0]);
var url=$("#room_form").attr("action");
$.ajax({
method: "POST",
data: formData,
url: url,
cache: false,
contentType: false,
processData: false,
})
.success(function(data) {
loaderHide();
setTimeout(function() {
window.location.reload();
}, 1000);
}).
fail(function(data) {
loaderHide();
});
The all above works fine.
problem:
when i select 3 files. and im showing those 3 files in the preview.
again i select another 2 files, now preview shows total 5 files.
But in <input type="file" there will be only 2 files. i searched and found it is the default behavior.
Tried:
Preview image:
Preview code:
In the image source im having original image as base 64 encoded image. i need to send this image to php file. how can i do this?

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<input type="file" multiple accept="image/x-png,image/gif,image/jpeg" title="Upload Image" id="gallery_img" name="roomimage" />
<div class="gallery_section">
</body>
<script>
$(document).on('change','#gallery_img',function(evt){
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
return;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
$('.gallery_section').append('<span class="imgPreview"><img id="image" name="image[]" class="imageThumb" src="'+e.target.result+'"><span class="remove icon-error" title="Close"></span></span>');
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
});
</script>
</html>

Related

Rails: field_tag with javascript to preview files not working correctly

I have a file_field_tag inside a rails form with a select file field:
<%= file_field_tag "attachments[media_files][]", multiple: true, id: "files" %>
And I have an area to preview the images/videos and remove if need be:
<span id="result"></span>
Everything is working correct but there is only one glitch.... If the images/videos are in separate folders, I have to add the files from one folder first and then from the other folder. But after this process only the second batch of files gets saved.
Here is the javascript for all of the above:
window.onload = function(){
//Check File API support
if(window.File && window.FileList && window.FileReader)
{
var filesInput = document.getElementById("files");
filesInput.addEventListener("change", function(event){
var files = event.target.files; //FileList object
var output = document.getElementById("result");
for(var i = 0; i< files.length; i++)
{
var file = files[i];
//Allowed files
//if (!file.type.match(/.(jpg|jpeg|png|gif|mp4|avi|flv|wmv|mov|tiff|bmp|exif)$/i))
//continue;
var picReader = new FileReader();
picReader.addEventListener("load",function(event){
var picFile = event.target;
var span = document.createElement("span");
span.innerHTML = ['<img class="thumb" src="', picFile.result, '" title="', picFile.name, '"/><span class="remove_img_preview"></span>'].join('');
output.insertBefore(span,null);
span.children[1].addEventListener("click", function(event){
span.parentNode.removeChild(span);
});
});
//Read the image
picReader.readAsDataURL(file);
}
});
}
else
{
console.log("Your browser does not support File API");
alert("Your browser does not support File API")
}
}
Any ideas on how to fix this glitch??

Is there a way not to let a blob (createObjectURL) show the image which is a GIF file but has a .jpeg extension?

Using blueimp, I'm making a file upload module and I will show an image thumbnail before people upload the image.
My code contains the following:
$('.fileupload').fileupload({
dataType: 'json',
autoUpload: false,
acceptFileTypes: /(\.|\/)(jpe?g|png)$/i,
maxNumberOfFiles: 1,
maxFileSize: 3000000,//3MB
loadImageMaxFileSize: 3000000,//3MB
}).on('fileuploadsubmit', function (e, data) {
}).on('fileuploadadd', function (e, data) {
data.context = $('<div/>').appendTo('.files');
$.each(data.files, function (index, file) {
// ファイル情報を表示する
var node = $('<p/>')
.append($('<span/>').text(file.name));
// プレビューを表示する
if (!index) {
node.append('<br>');
if((/\.(jpe?g|png)$/i).test(data.files[0].name))
{
node.append('<img class= "uploaded-image" src="'
+ URL.createObjectURL(data.files[0]) + '"/><br>');
}
node.append(uploadButton.clone(true).data(data))
.append(cancelButton);
}
node.appendTo(data.context);
});
}) // .on(... code following
It works well, but if people change a GIF file extension to ".jpeg" and upload it, the blob will also work well to show the GIF and, I think it's not safe. Is there a way not let blob to show the thumbnail In this case?
When submit the file, I'm checking the file in the server side if the file is really an image file (although it has a valid extension).
(this link helped me)
The code below worked well:
if (!index) {
node.append('<br>');
if((/\.(jpe?g|png)$/i).test(data.files[0].name))
{
if (window.FileReader && window.Blob)
{
var blob = data.files[0]; // See step 1 above
var fileReader = new FileReader();
fileReader.onloadend = function(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var header = "";
for(var i = 0; i < arr.length; i++) {
header += arr[i].toString(16);
}
if((header == "89504e47") || (header.substr(0,6) == "ffd8ff"))
{
$("button.upload").before('<img class= "uploaded-image" src="' + URL.createObjectURL(data.files[0]) + '"/><br>');
$(".file_upload").attr("style", "height: 600px; overflow-y: auto");
}
else
{
$("button.upload").prop('disabled', true);
var error = $('<span class="text-danger"/>').text(msg[4]);
$('.files').append('<br>').append(error);
}
};
fileReader.readAsArrayBuffer(blob);
}
}
node.append(uploadButton.clone(true).data(data))
.append(cancelButton);
}

HTML5 input type="file" doesn't trigger handleFileSelect()

I have this JS code for uploading a .jpg file to firebase:
function handleFileSelect(evt) {
var f = evt.target.files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
var filePayload = e.target.result;
// Generate a location that can't be guessed using the file's contents and a random number
var hash = CryptoJS.SHA256(Math.random() + CryptoJS.SHA256(filePayload));
var f = new Firebase(firebaseRef + 'pano/' + hash + '/filePayload');
spinner.spin(document.getElementById('spin'));
// Set the file payload to Firebase and register an onComplete handler to stop the spinner and show the preview
f.set(filePayload, function() {
spinner.stop();
document.getElementById("pano").src = e.target.result;
$('#file-upload').hide();
// Update the location bar so the URL can be shared with others
window.location.hash = hash;
});
};
})(f);
reader.readAsDataURL(f);
}
$(function() {
$('#spin').append(spinner);
var idx = window.location.href.indexOf('#');
var hash = (idx > 0) ? window.location.href.slice(idx + 1) : '';
if (hash === '') {
// No hash found, so render the file upload button.
$('#file-upload').show();
document.getElementById("file-upload").addEventListener('change', handleFileSelect, false);
} else {
// A hash was passed in, so let's retrieve and render it.
spinner.spin(document.getElementById('spin'));
var f = new Firebase(firebaseRef + '/pano/' + hash + '/filePayload');
f.once('value', function(snap) {
var payload = snap.val();
if (payload != null) {
document.getElementById("pano").src = payload;
} else {
$('#body').append("Not found");
}
spinner.stop();
});
}
});
My js imports:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="//cdn.firebase.com/v0/firebase.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/spin.js/1.2.7/spin.min.js"></script>
<script src="sha256.js"></script>
<script src="firepano.js"></script>
My html looks something like this:
<input type="file" accept="image/*" capture="camera" id="file-upload">
Of course this is just a piece, but somehow the js function isn't triggered when I select a file, only if I put the HTML code outside of my file in a separate file and leave only this input tag. Is there some other piece of code that can interfier in the selectfile function trigger?
Try this:
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="image">
<input type="submit" value="Upload">
</form>

how can I see a preview of uploaded image (don!) and then save it's address?

I want to upload an image
but first I want to see a preview of image and after that when user click on another asp:button, save the image.
for the preview part, I use below code:
<script src="//code.jquery.com/jquery.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script>
jQuery(document).ready(function ($) {
$('#image').on('change', function (event) {
var image = this.files[0];
$('#singlePreview').html('');
var reader = new FileReader();
reader.onload = function (e) {
$('<img src="' + e.target.result + '" class="thumbnail img-responsive" width="150" alt="Loading..">').appendTo($('#singlePreview'));
}
reader.readAsDataURL(image);
});
});
</script>
& in HTML format:
<div class="form-group">
<label for="image">image</label>
<input type="file" id="image" accept="image/*" />
</div>
<div id="singlePreview"></div>
but now I don't know how to save the uploaded image URL. because I don't know anything about JavaScript or jquery...
I know that this.files[0] is my address. but i want to use it at code behind (C#).
You can make an ajax call for uploading images
// var file;
$('#image').on('change', function (event) {
var image = this.files[0];
$('#singlePreview').html('');
var reader = new FileReader();
reader.onload = function (e) {
$('<img src="' + e.target.result + '" class="thumbnail img-responsive" width="150" alt="Loading..">').appendTo($('#singlePreview'));
}
reader.readAsDataURL(image);
//file=this.files[0];
});
//This is your button click
$("#btnUpload").on('click',function(){
uploadFile();
});
function uploadFile() {
var formData = new FormData();
formData.append('file', $('#image')[0].files[0]);
$.ajax({
type: 'post',
url: 'pathTo/genericHandler.ashx',
data: formData,
success: function (status) {
alert("Success")
},
error function (status) {
alert("Failed!");
},
processData: false,
contentType: false
});
}
Code Behind:
First, you need to add Generic Handler ( ashx file ) in your application. Below code will save the uploaded file
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
try
{
string dirFullPath = HttpContext.Current.Server.MapPath("~/MediaUploader/");
string[] files;
int numFiles;
files = System.IO.Directory.GetFiles(dirFullPath);
numFiles = files.Length;
numFiles = numFiles + 1;
string str_image = "";
foreach (string str in context.Request.Files)
{
HttpPostedFile file = context.Request.Files[str];
string fileName = file.FileName;
string fileExtension = file.ContentType;
if (!string.IsNullOrEmpty(fileName))
{
fileExtension = Path.GetExtension(fileName);
str_image = "MyPHOTO_" + numFiles.ToString() + fileExtension;
string pathToSave = HttpContext.Current.Server.MapPath("~/MediaUploader/") + str_image;
file.SaveAs(pathToSave);
}
}
// database record update logic here ()
context.Response.Write(str_image);
}
catch (Exception ac)
{
}
}

Send a file from HTML/Javascript to Ruby to API

I'm writing an app that uploads multiple posts to Tumblr. I'm using Ruby with Sinatra, and since I'm new to both I was wondering how to actually use the files uploaded using the HTML5 multiple file reader.
Here is my Ruby pseudocode in app.rb:
post '/' do |file|
if file is text file
##client.text("#{session[:user_id]}.tumblr.com", {:body => "Stuff from index.erb"})
elsif file is photo file
##client.photo("#{session[:user_id]}.tumblr.com", {:data => ['/path/to/pic.jpg']})
else
"Sorry, text and photo only at this time."
end
end
And here's my HTML/Javascript in index.erb:
<body>
<h1>File Uploader</h1>
<form method="post">
<input type="file" id="files" name="files[]" multiple="multiple">
<output id="list"></output>
<div id="progress_bar"><div class="percent">0%</div></div>
<input type="submit" value="Post Something!">
</form>
<!-- FILE LOADER -->
<script>
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
<!-- PROGRESS BAR -->
<script>
var reader;
var progress = document.querySelector('.percent');
function abortRead() {
reader.abort();
}
function errorHandler(evt) {
switch(evt.target.error.code) {
case evt.target.error.NOT_FOUND_ERR:
alert('File Not Found!');
break;
case evt.target.error.NOT_READABLE_ERR:
alert('File is not readable');
break;
case evt.target.error.ABORT_ERR:
break; // noop
default:
alert('An error occurred reading this file.');
};
}
function updateProgress(evt) {
// evt is an ProgressEvent.
if (evt.lengthComputable) {
var percentLoaded = Math.round((evt.loaded / evt.total) * 100);
// Increase the progress bar length.
if (percentLoaded < 100) {
progress.style.width = percentLoaded + '%';
progress.textContent = percentLoaded + '%';
}
}
}
function handleFileSelect(evt) {
// Reset progress indicator on new file selection.
progress.style.width = '0%';
progress.textContent = '0%';
reader = new FileReader();
reader.onerror = errorHandler;
reader.onprogress = updateProgress;
reader.onabort = function(e) {
alert('File read cancelled');
};
reader.onloadstart = function(e) {
document.getElementById('progress_bar').className = 'loading';
};
reader.onload = function(e) {
// Ensure that the progress bar displays 100% at the end.
progress.style.width = '100%';
progress.textContent = '100%';
setTimeout("document.getElementById('progress_bar').className='';", 2000);
}
// Read in the image file as a binary string.
reader.readAsBinaryString(evt.target.files[0]);
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
</body>
Once I have the actual file objects, I can send them to Tumblr via the Ruby code, BUT I don't really know how to get the file from index.erb to the Ruby code. Should I put the Ruby code inside the .erb file?
TL;DR:
1.) How can I convert whatever the Javascript returns into a readable file for Ruby? I want to return the photos as files, and the text as parseable text.
2.) How can I send the file returned by Javascript to Ruby to send to Tumblr?

Categories