I'm trying to add a multiple image up-loader which returns a JavaScript array that is populated by the user selecting images. I will be using this image up-loader with other input form elements which will all submit together, in this case i'm not using AJAX. The maximum file upload size is 2MB. The JavaScript array contains the base 64 encoded image with all the details including size, type etc.
I have used $('#j_son').val(JSON.stringify(AttachmentArray)); outside the array to populate the hidden input field everytime the array is populated (input unhidden to show JSON string). Lightweight Multiple File Upload with Thumbnail Preview using HTML5 and Client Side Scripts
On submit I will use PHP to decode the new JSON string and and put the multiple images in a folder called uploads.
The problem I am facing is that selecting image attachments larger than 200 KB seem to slow the output of images inside the div container and the JSON string inside the hidden input field and anything to large will cause "aw snap" error inside chrome and crash the browser, I don't know where I'm going wrong. I also have a click event that when the user clicks X remove button and the hidden input field is repopulated with the updated JSON array, this to is really slow and crashes if the files are to large. The PHP side of things has no problem decoding the JSON string it seems to either fall on the JavaScript code or the extra functionality I have added at the bottom of the script. Is there a way to stop this from happening? I have added the full code including the PHP if anybody wants to test it.
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<style>
/*Copied from bootstrap to handle input file multiple*/
.btn {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: normal;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
}
/*Also */
.btn-success {
border: 1px solid #c5dbec;
background: #D0E5F5;
font-weight: bold;
color: #2e6e9e;
}
/* This is copied from https://github.com/blueimp/jQuery-File-
Upload/blob/master/css/jquery.fileupload.css */
.fileinput-button {
position: relative;
overflow: hidden;
}
.fileinput-button input {
position: absolute;
top: 0;
right: 0;
margin: 0;
opacity: 0;
-ms-filter: 'alpha(opacity=0)';
font-size: 200px;
direction: ltr;
cursor: pointer;
}
.thumb {
height: 80px;
width: 100px;
border: 1px solid #000;
}
ul.thumb-Images li {
width: 120px;
float: left;
display: inline-block;
vertical-align: top;
height: 120px;
}
.img-wrap {
position: relative;
display: inline-block;
font-size: 0;
}
.img-wrap .close {
position: absolute;
top: 2px;
right: 2px;
z-index: 100;
background-color: #D0E5F5;
padding: 5px 2px 2px;
color: #000;
font-weight: bolder;
cursor: pointer;
opacity: .5;
font-size: 23px;
line-height: 10px;
border-radius: 50%;
}
.img-wrap:hover .close {
opacity: 1;
background-color: #ff0000;
}
.FileNameCaptionStyle {
font-size: 12px;
}
</style>
<script type="text/javascript" src="scripts/jquery-1.10.2.js"></script>
<script type="text/javascript">
//I added event handler for the file upload control to access the files
properties.
document.addEventListener("DOMContentLoaded", init, false);
//To save an array of attachments
var AttachmentArray = [];
$('#j_son').val(JSON.stringify(AttachmentArray));
//counter for attachment array
var arrCounter = 0;
//to make sure the error message for number of files will be shown only
one time.
var filesCounterAlertStatus = false;
//un ordered list to keep attachments thumbnails
var ul = document.createElement('ul');
ul.className = ("thumb-Images");
ul.id = "imgList";
function init() {
//add javascript handlers for the file upload event
document.querySelector('#files').addEventListener('change',
handleFileSelect, false);
}
//the handler for file upload event
function handleFileSelect(e) {
//to make sure the user select file/files
if (!e.target.files) return;
//To obtaine a File reference
var files = e.target.files;
// Loop through the FileList and then to render image files as
thumbnails.
for (var i = 0, f; f = files[i]; i++) {
//instantiate a FileReader object to read its contents into
memory
var fileReader = new FileReader();
// Closure to capture the file information and apply validation.
fileReader.onload = (function (readerEvt) {
return function (e) {
//Apply the validation rules for attachments upload
ApplyFileValidationRules(readerEvt)
//Render attachments thumbnails.
RenderThumbnail(e, readerEvt);
//Fill the array of attachment
FillAttachmentArray(e, readerEvt)
};
})(f);
// Read in the image file as a data URL.
// readAsDataURL: The result property will contain the
//file/blob's data encoded as a data URL.
// More info about Data URI scheme
//https://en.wikipedia.org/wiki/Data_URI_scheme
fileReader.readAsDataURL(f);
}
document.getElementById('files').addEventListener('change',
handleFileSelect, false);
}
//To remove attachment once user click on x button
jQuery(function ($) {
$('div').on('click', '.img-wrap .close', function () {
var id = $(this).closest('.img-wrap').find('img').data('id');
//to remove the deleted item from array
var elementPos = AttachmentArray.map(function (x) { return
x.FileName; }).indexOf(id);
if (elementPos !== -1) {
AttachmentArray.splice(elementPos, 1);
}
//to remove image tag
$(this).parent().find('img').not().remove();
//to remove div tag that contain the image
$(this).parent().find('div').not().remove();
//to remove div tag that contain caption name
$(this).parent().parent().find('div').not().remove();
//to remove li tag
var lis = document.querySelectorAll('#imgList li');
for (var i = 0; li = lis[i]; i++) {
if (li.innerHTML == "") {
li.parentNode.removeChild(li);
}
}
});
}
)
//Apply the validation rules for attachments upload
function ApplyFileValidationRules(readerEvt)
{
//To check file type according to upload conditions
if (CheckFileType(readerEvt.type) == false) {
alert("The file (" + readerEvt.name + ") does not match the
upload conditions, You can only upload jpg/png/gif files");
e.preventDefault();
return;
}
//To check file Size according to upload conditions
if (CheckFileSize(readerEvt.size) == false) {
alert("The file (" + readerEvt.name + ") does not match the
upload conditions, The maximum file size for uploads should not
exceed 300 KB");
e.preventDefault();
return;
}
//To check files count according to upload conditions
if (CheckFilesCount(AttachmentArray) == false) {
if (!filesCounterAlertStatus) {
filesCounterAlertStatus = true;
alert("You have added more than 10 files. According to
upload conditions you can upload 10 files maximum");
}
e.preventDefault();
return;
}
}
//To check file type according to upload conditions
function CheckFileType(fileType) {
if (fileType == "image/jpeg") {
return true;
}
else if (fileType == "image/png") {
return true;
}
else if (fileType == "image/gif") {
return true;
}
else if (fileType == "image/jpg") {
return true;
}
else {
return false;
}
return true;
}
//To check file Size according to upload conditions
function CheckFileSize(fileSize) {
if (fileSize < 2000000) {
return true;
}
else {
return false;
}
return true;
}
//To check files count according to upload conditions
function CheckFilesCount(AttachmentArray) {
//Since AttachmentArray.length return the next available index in
//the array,
//I have used the loop to get the real length
var len = 0;
for (var i = 0; i < AttachmentArray.length; i++) {
if (AttachmentArray[i] !== undefined) {
len++;
}
}
//To check the length does not exceed 10 files maximum
if (len > 9) {
return false;
}
else
{
return true;
}
}
//Render attachments thumbnails.
function RenderThumbnail(e, readerEvt)
{
var li = document.createElement('li');
ul.appendChild(li);
li.innerHTML = ['<div class="img-wrap"> <span class="close">×
</span>' +
'<img class="thumb" src="', e.target.result, '" title="',
escape(readerEvt.name), '" data-id="',
readerEvt.name, '"/>' + '</div>'].join('');
var div = document.createElement('div');
div.className = "FileNameCaptionStyle";
li.appendChild(div);
div.innerHTML = [readerEvt.name].join('');
document.getElementById('Filelist').insertBefore(ul, null);
}
//Fill the array of attachment
function FillAttachmentArray(e, readerEvt)
{
AttachmentArray[arrCounter] =
{
AttachmentType: 1,
ObjectType: 1,
FileName: readerEvt.name,
FileDescription: "Attachment",
NoteText: "",
MimeType: readerEvt.type,
Content: e.target.result.split("base64,")[1],
FileSizeInBytes: readerEvt.size,
};
arrCounter = arrCounter + 1;
//THIS IS THE PART I ADDED TO POPULATE THE HIDDEN INPUT FIELD
$('#j_son').val(JSON.stringify(AttachmentArray));
}
//THIS IS TO UPDATE THE INPUT FIELD WHEN A FILE IS REMOVED
$(document).on('click', '.close', function(){
var myString = JSON.stringify(AttachmentArray);
$('#j_son').val(myString);
});
</script>
</head>
<body>
<div>
<label style="font-size: 14px;">
<span style='color:navy;font-weight:bold'>Attachment Instructions :
</span>
</label>
<ul>
<li>
Allowed only files with extension (jpg, png, gif)
</li>
<li>
Maximum number of allowed files 10 with 2 MB for each
</li>
<li>
you can select files from different folders
</li>
</ul>
<form method="POST" action="" enctype="multipart/form-data">
<span class="btn btn-success fileinput-button">
<span>Select Attachment</span>
<input type="file" name="files[]" id="files" multiple
accept="image/jpeg, image/jpg image/png, image/gif,"><br />
</span>
<!--input field to be populated by the array-->
<input type="text" name="j_son" id="j_son" style="width: 500px;">
<!--Submit and post to get decoded JSON string-->
<button type="submit" id="image_post" name="post_it">Submit</button>
</form>
<output id="Filelist"></output>
</div>
<?php
if(isset($_POST['post_it']))
{
//other input fields
$file = $_POST['j_son'];
$tempData = html_entity_decode($file);
$cleanData = json_decode($tempData, true);
foreach($cleanData as $p)
{
echo $p['Content']."</br>";
//insert code to uploads folder
}
}
?>
</body>
</html>
-- edit --
This may be because of a known issue in chrome. Try using a blob as recommended in this post
How can javascript upload a blob?
function uploadAudio( blob ) {
var reader = new FileReader();
reader.onload = function(event){
var fd = {};
fd["fname"] = "test.wav";
fd["data"] = event.target.result;
$.ajax({
type: 'POST',
url: 'upload.php',
data: fd,
dataType: 'text'
}).done(function(data) {
console.log(data);
});
};
reader.readAsDataURL(blob);
}
-- /edit --
ok it seems like you are adding an onChange event listener multiple times to the "files" id. Once in the init and once every time the handleFileSelect function is called. This could for sure be your slowdown problem.
Also, if you are going to have a file upload size that maxes out at 2MB you should set this in your PHP file using upload_max_filesize and also set post_max_size.
ini_set('upload_max_filesize', '2M');
ini_set('post_max_size', '2M');
from php.net:
upload_max_filesize
The maximum size of an uploaded file.
post_max_size
Sets max size of post data allowed. This setting also affects file upload. To upload large files, this value must be larger than upload_max_filesize. Generally speaking, memory_limit should be larger than post_max_size. When an integer is used, the value is measured in bytes.
Also if your upload ends up timing out you might also want to extend the execution time by using max_input_time or max_execution time though I think that max_input_time should be enough.
ini_set('max_input_time', 300);
ini_set('max_execution_time', 300);
max_input_time
This sets the maximum time in seconds a script is allowed to parse input data, like POST and GET. Timing begins at the moment PHP is invoked at the server and ends when execution begins. The default setting is -1, which means that max_execution_time is used instead. Set to 0 to allow unlimited time.
max_execution_time
This sets the maximum time in seconds a script is allowed to run before it is terminated by the parser. This helps prevent poorly written scripts from tying up the server. The default setting is 30. When running PHP from the command line the default setting is 0.
This needs to be added at the top of your PHP file before other output.
Related
I have JSON file which contains video data eg video title and video link.
Here is jsffiddle:demo
Here is a JSON file sample:
[{
"title": "How to create video?",
"link": "https://storage.googleapis.com/coverr-main/mp4/Sunset-Desert-Run.mp4"
},
{
"title": "How to add audio?",
"link": "https://app.coverr.co/s3/mp4/Sand-Slow-Walk.mp4"
},
{
"title": "How to add music?",
"link": "https://app.coverr.co/s3/mp4/Steaming-Yellowstone.mp4"
},
{
"title": "How to add scene?",
"link": "https://app.coverr.co/s3/mp4/Skater-in-the-Park.mp4"
},
{
"title": "How to preview a video?",
"link": "https://app.coverr.co/s3/mp4/Stop-Sign.mp4"
},
{
"title": "How to delete video?",
"link": "https://app.coverr.co/s3/mp4/RV-Park.mp4"
}
]*
I want when the user clicks a prev button it should play the previous video and display video title too if the user clicks next button it should play the next video and display video title too. here is visual how it looks.
here is what I have tried so far.
HTML
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<div id="video-container">
<h1 class="movie-title">Movie title</h1>
<video class="videoplayer" id="video-player_transformed"
playsinline autoplay muted>
<source src="https://app.coverr.co/s3/mp4/Sand-Slow-Walk.mp4"
type="video/mp4">
</video>
</div>
<div class="btns">
<div class="prev">
Prev
</div>
<div class="next">
next
</div>
</div>
Here is CSS
body{
background: gray;
}
#video-container{
position: relative;
height: 314px;
width: 800px;
display: flex;
justify-content: center;
align-self: center;
overflow: hidden;
}
.movie-title{
position: absolute;
top: 0px;
}
.btns{
display: flex;
justify-content: center;
}
.prev, .next{
display: flex;
width: 100px;
height: 50px;
background: red;
margin: 20px;
justify-content: center;
align-items: center;
color: white;
cursor: pointer;
}
video{
height: 400px;
width: 400px;
}
Here is JS
$(document).ready(function () {
var myData;
$.ajax({
dataType: 'json',
url: 'https://videomill-bot.audiencevideo.com/videoexplainer/videoexplainer/data/video.json',
data: myData,
success: function(data) {
console.log($('.videoplayer').append(myData));
myData = myData;
},
})
var player = document.querySelector('#videoplayer');
var i = 0;
var prev = document.querySelector('.prev');
var next = document.querySelector('.next');
prev.addEventListener('click',function(){
player.src = myData[i == 0 ? myData.length-- : i--];
video.play();
},false);
next.addEventListener('click',function(){
player.src = myData[i ==myData.length-- ? 0 : i++];
video.play();
},false);
player.src = myData[i];
player.play(); //init the video player
});
Unfortunately, I am getting the following error after clicking buttons next or prev.
Uncaught TypeError: Cannot read property 'length' of undefined
What do I need to change to get what I want? any help or suggestion will be apreciated thanks.
Your issue is because the code after the .ajax() request is running before the request has completed, meaning the myData variable has no accessible data.
To solve this you could try something like the modified example below.
(function($) {
'use strict';
/**
* Ajax response data will be stored in this local variable
* #var {Array}
*/
var myData = [];
/**
* jQuery video element
* #var {Object}
*/
var $player = $('video.videoplayer');
/**
* jQuery movie title element
* #var {Object}
*/
var $title = $('.movie-title');
/**
* jQuery previous button element
* #var {Object}
*/
var $prev = $('.prev');
/**
* jQuery next button element
* #var {Object}
*/
var $next = $('.next');
/**
* Custom jQuery function to add sources to a media element
* #param {Array|String} sources
*/
$.fn.setSource = function(sources) {
// Get the media tag (video/audio)
var tag = this.prop('tagName').toLowerCase();
// Clear any existing sources
this.empty();
// Check if sources paramater is an array
if (Array.isArray(sources)) {
// Loop through each source
for (let i = 0; i < sources.length; i++) {
var src = sources[i];
var type = /(?:\.([^.]+))?$/.exec(src); // Get file extention (.mp4, .ogv, .webm etc)
if (type[0]) {
type = type[0].replace('.', '');
}
// Create and append a source tag
this.append($('<source>', {
src: src,
type: tag + '/' + type
}));
}
} else {
this.attr('src', sources);
}
};
/**
* Reusable function to update player element
* #param {Object} data Expects an object with `link` and `title` attributes
*/
function updatePlayer(data) {
$player.setSource(data.link); // Set the video source
$title.text(data.title); // Add the title
}
// Disable actions because we have no data
$prev.prop('disabled', true);
$next.prop('disabled', true);
// Send request to server to recieve data
$.ajax({
dataType: 'json',
url: 'https://videomill-bot.audiencevideo.com/videoexplainer/videoexplainer/data/video.json'
}).then(function(data) {
myData = data; // replace `myData` with the ajax response data
// Check if we have data
if (myData && myData.length) {
// Re-enable actions because we have data
$prev.prop('disabled', false);
$next.prop('disabled', false);
updatePlayer(data); // Set the video source (see functions above)
$player.get(0).play(); // Play the html5 video*
// *Most browsers will not allow playing without any user interaction
}
}).fail(function(error) {
// Request failed, inform user
alert('There was an error downloading videos, please refresh and try again.');
console.warn(error);
});
// On click set video element to PREVIOUS video in myData
$prev.on('click', function() {
// Check if we have data before attempting to access it
if (myData && myData.length) {
updatePlayer(myData[i === 0 ? myData.length - 1 : --i]);
$player.get(0).play();
}
// Prevent default click action
return false;
});
// On click set video element to NEXT video in myData
$next.on('click', function() {
// Check if we have data before attempting to access it
if (myData && myData.length) {
updatePlayer(myData[i === myData.length - 1 ? 0 : ++i]);
$player.get(0).play();
}
// Prevent default click action
return false;
});
})(jQuery || window.jQuery);
(this hasn't been tested and there are many ways to achieve what you are aiming to do but it should give you an idea of where to start.)
A few things to note:
You are using jQuery so I have updated element selectors to make the most out of it.
In your ajax success function you we're redefining myData as its self and not with the response data (myData = myData changed to myData = data)
I have created functions to try and mitigate code duplication.
Finally, be careful autoplaying media elements with javascript as browser restrictions apply.
HELP!!!
I have been struggling trying to find out how to retrieve the paths of the files that have been uploaded on a FilePond form
This is the code that I have so far
<script src="https://unpkg.com/filepond-plugin-file-encode/dist/filepond-plugin-file-encode.min.js"></script>
<script src="https://unpkg.com/filepond-plugin-file-validate-size/dist/filepond-plugin-file-validate-size.min.js"></script>
<script src="https://unpkg.com/filepond-plugin-image-exif-orientation/dist/filepond-plugin-image-exif-orientation.min.js"></script>
<script src="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.js"></script>
<script src="https://unpkg.com/filepond/dist/filepond.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css">
<link rel="stylesheet" href="https://unpkg.com/filepond/dist/filepond.min.css">
<!--
The classic file input element we'll enhance to a file pond
-->
<!--
The classic file input element we'll enhance
to a file pond, configured with attributes
-->
<input type="file"
class="filepond"
name="filepond"
id="DragInput"
multiple
data-max-file-size="9MB"
data-max-files="3">
<button class="submit_files">Submit</button>
<style>
/**
* FilePond Custom Styles
*/
.filepond {
margin-top: 14px;
margin-bottom: -4px;
}
.filepond--root {
font-size: 11px;
}
.filepond--drop-label {
font-size: 14px;
transform: translate3d(0px, 0px, 0);
opacity: 1;
color: black;
}
.filepond--drop-label {
color: #4c4e53;
}
.filepond--label-action {
-webkit-text-decoration-color: #babdc0;
text-decoration-color: #babdc0;
}
.filepond--panel-root {
border-radius: 2em;
background-color: #edf0f4;
height: 1em;
}
.filepond--item-panel {
background-color: #595e68;
}
.filepond--drip-blob {
background-color: #7f8a9a;
}
</style>
<script>
// We want to preview images, so we register
// the Image Preview plugin, We also register
// exif orientation (to correct mobile image
// orientation) and size validation, to prevent
// large files from being added
FilePond.registerPlugin(
FilePondPluginImagePreview,
FilePondPluginImageExifOrientation,
FilePondPluginFileValidateSize
);
// Select the file input and use
// create() to turn it into a pond
FilePond.create(
document.getElementById('DragInput')
);
$('.filepond').on('FilePond:addfile', function(error, file) {
if (error) {
console.log('File Add Error: ' , error);
return;
}
console.log('File Added', file.filename);
});
var handler = function(fieldName, file, metadata, load, error, progress, abort) {
// Custom ajax file upload or local storing here
// Call the error method if something is wrong, should exit after
error('Error occurred');
// Call the progress method to update the progress to 100% before calling load
// Setting computable to false switches the loading indicator to infinite mode
// (computable, processedSize, totalSize)
progress(true, 0, 1024);
// Call the load method when done and pass the returned server file id
// the load method accepts either a string (id) or an object
// the unique server file id is used by revert and restore functions
load('unique-file-id');
// Abort method so the request can be cancelled by user
return {
abort: function() {
// User tapped abort, cancel ongoing actions here
// Let FilePond know the request has been cancelled
abort();
}
};
};
</script>
<!-- file upload itself is disabled in this pen -->
when the user clicks on the submit button I want the paths of the files that have been uploaded to the FilePond form listed in the console
Thanks,
Arnav
As far as I can tell this is not possible, browsers simply do not expose file path information. https://github.com/pqina/filepond/issues/254#issuecomment-475181033
If you have/find resources that show otherwise I'm happy to adjust the codebase to make file items contain the path info.
enter image description herepreview uploaded images after upload.and to show the image on the form.Want to achieve this with help of jquery image upload with Laravel framework. help is appreciated.
#Simon I have implemented ur code.its working,but one image is shown in view and i want to show all three images,which are selected.Plz helpenter image description here
if you using the standard file input type and say your using a moderish browser etc then you could try the following.
$('#addImage').on('change', function(evt) {
var selectedImage = evt.currentTarget.files[0];
var imageWrapper = document.querySelector('.image-wrapper');
var theImage = document.createElement('img');
imageWrapper.innerHTML = '';
var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.jpg|.jpeg|.gif|.png|.bmp)$/;
if (regex.test(selectedImage.name.toLowerCase())) {
if (typeof(FileReader) != 'undefined') {
var reader = new FileReader();
reader.onload = function(e) {
theImage.id = 'new-selected-image';
theImage.src = e.target.result;
imageWrapper.appendChild(theImage);
}
//
reader.readAsDataURL(selectedImage);
} else {
//-- Let the user knwo they cannot peform this as browser out of date
console.log('browser support issue');
}
} else {
//-- no image so let the user knwo we need one...
$(this).prop('value', null);
console.log('please select and image file');
}
});
.wrapper {
padding: 25px;
}
.image-wrapper {
padding: 5px;
border: 1px #ddd solid;
height auto;
width: 200px;
}
.image-wrapper img {
max-width: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<input type="file" id="addImage" />
</div>
<div class="image-wrapper">
</div>
also viewable on codepen Exmaple
below is my snippet, and what I'm trying to do is render the selected image (from the input file) to the specified image container ("#test_image") but unfortunately, it looks like missed up and sadly not working. Any ideas, help?
var prev_image;
$(document).ready(function(){
$("input[type='file']").change(function(){
//get the val of the previous image for the reset use later
prev_image = $("#test_image").attr("src");
//render the selected image on the image box (test_image)
$("#test_image").attr("src", $(this).val());
})
});
#test_image{
width: 100px;
height: 100px;
-webkit-border-radius: 50%;-moz-border-radius: 50%;border-radius: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="test_image" src="data:image/jpg;base64,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"/>
<input type="file" />
HTML5 comes with File API spec, which allows you to create applications that let the user interact with files locally; That means you can load files and render them in the browser without actually having to upload the files. Part of the File API is the FileReader interface which lets web applications asynchronously read the contents of files .
var prev_image;
$(document).ready(function(){
$("input[type='file']").change(function(){
// handle input changes
prev_image = $("#test_image").attr("src");
// grab the first image in the FileList object and pass it to the function
renderImage(this.files[0])
});
});
// render the image in our view
function renderImage(file) {
// generate a new FileReader object
var reader = new FileReader();
// inject an image with the src url
reader.onload = function(event) {
the_url = event.target.result
$('#test_image').attr('src',the_url);
}
// when the file is read it triggers the onload event above.
reader.readAsDataURL(file);
}
#test_image{
width: 100px;
height: 100px;
-webkit-border-radius: 50%;-moz-border-radius: 50%;border-radius: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="test_image" src="data:image/jpg;base64,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"/>
<input type="file" />
One of Sort trick
<input type="file" onchange="$('#test_image')[0].src = window.URL.createObjectURL(this.files[0])" />
here the fiddle
http://jsfiddle.net/LvsYc/7050/
You need to read the file using file api to set the src of the image
var prev_image;
$(document).ready(function() {
$("input[type='file']").change(function() {
//get the val of the previous image for the reset use later
prev_image = $("#test_image").prop("src");
var reader = new FileReader();
reader.onloadend = function() {
$("#test_image").prop("src", reader.result);
}
if (this.files && this.files[0]) {
reader.readAsDataURL(this.files[0]);
} else {
$("#test_image").prop("src", "");
}
})
});
#test_image {
width: 100px;
height: 100px;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
border-radius: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="test_image" src="data:image/jpg;base64,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"
/>
<input type="file" />
Use Html2Canvas for taking screen shot .Its very easy .. just include the html2canvas js files.. you will get from Here
and some simple codes . Refer this -> Click Here
It will work for you .
In your case you can use a temp image path.
Here is the fiddle: http://jsfiddle.net/swaprks/91Lphm16/
CSS:
#test_image{
width: 100px;
height: 100px;
-webkit-border-radius: 50%;-moz-border-radius: 50%;border-radius: 50%;
}
JS:
var prev_image;
$(document).ready(function(){
$("input[type='file']").change(function(event){
var tmppath = URL.createObjectURL(event.target.files[0]);
//get the val of the previous image for the reset use later
prev_image = $("#test_image").attr("src");
//render the selected image on the image box (test_image)
$("#test_image").attr("src", tmppath);
})
});
HTML:
<img id="test_image" src="data:image/jpg;base64,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"/>
<input type="file" />
Try this. Do some tweeking as per your need
var prev_image;
$(document).ready(function(){
$("input[type='file']").change(function(){
var tmpImageData = new FileReader();
tmpImageData.onload = function (e) {
//get the val of the previous image for the reset use later
prev_image = $("#test_image").attr("src");
//render the selected image on the image box (test_image)
$("#test_image").attr("src", e.target.result);
}
tmpImageData.readAsDataURL(input.files[0]);
})
});
Can I kindly ask for a good working example of HTML5 File Drag and Drop implementation? The source code should work if drag and drop is performed from external application(Windows Explorer) to browser window. It should work on as many browsers as possible.
I would like to ask for a sample code with good explanation. I do not wish to use third party libraries, as I will need to modify the code according to my needs. The code should be based on HTML5 and JavaScript. I do not wish to use JQuery.
I spent the whole day searching for good source of material, but surprisingly, I did not find anything good. The examples I found worked for Mozilla but did not work for Chrome.
Here is a dead-simple example. It shows a red square. If you drag an image over the red square it appends it to the body. I've confirmed it works in IE11, Chrome 38, and Firefox 32. See the Html5Rocks article for a more detailed explanation.
var dropZone = document.getElementById('dropZone');
// Optional. Show the copy icon when dragging over. Seems to only work for chrome.
dropZone.addEventListener('dragover', function(e) {
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
});
// Get file data on drop
dropZone.addEventListener('drop', function(e) {
e.stopPropagation();
e.preventDefault();
var files = e.dataTransfer.files; // Array of all files
for (var i=0, file; file=files[i]; i++) {
if (file.type.match(/image.*/)) {
var reader = new FileReader();
reader.onload = function(e2) {
// finished reading file data.
var img = document.createElement('img');
img.src= e2.target.result;
document.body.appendChild(img);
}
reader.readAsDataURL(file); // start reading the file data.
}
}
});
<div id="dropZone" style="width: 100px; height: 100px; background-color: red"></div>
The accepted answer provides an excellent link for this topic; however, per SO rules, pure link answers should be avoided since the links can rot at any time. For this reason, I have taken the time to summarize the content of the link for future readers.
Getting Started
Prior to implementing a method to upload files to your website, you should ensure that the browsers you choose to support will be capable of fully supporting the File API. You can test this quickly with the snippet of Javascript below:
// Check for the various File API support.
if (window.File && window.FileReader && window.FileList && window.Blob) {
// Great success! All the File APIs are supported.
} else {
alert('The File APIs are not fully supported in this browser.');
}
You can modify the snippet above to meet your needs of course.
Form Input
The most common way to upload a file is to use the standard <input type="file"> element. JavaScript returns the list of selected File objects as a FileList.
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// files is a FileList of File objects. List some properties.
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
f.size, ' bytes, last modified: ',
f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
'</li>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
<input type="file" id="files" name="files[]" multiple />
<output id="list"></output>
Drag and Drop
Making simple modifications to the snippet above allows us to provide drag and drop support.
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
var files = evt.dataTransfer.files; // FileList object.
// files is a FileList of File objects. List some properties.
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
f.size, ' bytes, last modified: ',
f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
'</li>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
function handleDragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
}
// Setup the dnd listeners.
var dropZone = document.getElementById('drop_zone');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);
#drop_zone {
min-height: 10em;
background: #eee;
}
<div id="drop_zone">Drop files here</div>
<output id="list"></output>
Reading Files
Now you've obtained a reference to the File, you can instantiate a FileReader to read its contents into memory. When the load completes the onload event is fired and its result attribute can be used to access the file data. Feel free to look at the references for FileReader to cover the four available options for reading a file.
The example below filters out images from the user's selection, calls reader.readAsDataURL() on the file, and renders a thumbnail by setting the src attribute to a data URL.
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);
.thumb {
height: 75px;
border: 1px solid #000;
margin: 10px 5px 0 0;
}
<input type="file" id="files" name="files[]" multiple />
<output id="list"></output>
Slicing
In some cases reading the entire file into memory isn't the best option. For example, say you wanted to write an async file uploader. One possible way to speed up the upload would be to read and send the file in separate byte range chunks. The server component would then be responsible for reconstructing the file content in the correct order.
The following example demonstrates reading chunks of a file. Something worth noting is that it uses the onloadend and checks the evt.target.readyState instead of using the onload event.
function readBlob(opt_startByte, opt_stopByte) {
var files = document.getElementById('files').files;
if (!files.length) {
alert('Please select a file!');
return;
}
var file = files[0];
var start = parseInt(opt_startByte) || 0;
var stop = parseInt(opt_stopByte) || file.size - 1;
var reader = new FileReader();
// If we use onloadend, we need to check the readyState.
reader.onloadend = function(evt) {
if (evt.target.readyState == FileReader.DONE) { // DONE == 2
document.getElementById('byte_content').textContent = evt.target.result;
document.getElementById('byte_range').textContent =
['Read bytes: ', start + 1, ' - ', stop + 1,
' of ', file.size, ' byte file'].join('');
}
};
var blob = file.slice(start, stop + 1);
reader.readAsBinaryString(blob);
}
document.querySelector('.readBytesButtons').addEventListener('click', function(evt) {
if (evt.target.tagName.toLowerCase() == 'button') {
var startByte = evt.target.getAttribute('data-startbyte');
var endByte = evt.target.getAttribute('data-endbyte');
readBlob(startByte, endByte);
}
}, false);
#byte_content {
margin: 5px 0;
max-height: 100px;
overflow-y: auto;
overflow-x: hidden;
}
#byte_range { margin-top: 5px; }
<input type="file" id="files" name="file" /> Read bytes:
<span class="readBytesButtons">
<button data-startbyte="0" data-endbyte="4">1-5</button>
<button data-startbyte="5" data-endbyte="14">6-15</button>
<button data-startbyte="6" data-endbyte="7">7-8</button>
<button>entire file</button>
</span>
<div id="byte_range"></div>
<div id="byte_content"></div>
Monitoring Progress
One of the nice things that we get for free when using async event handling is the ability to monitor the progress of the file read; useful for large files, catching errors, and figuring out when a read is complete.
The onloadstart and onprogress events can be used to monitor the progress of a read.
The example below demonstrates displaying a progress bar to monitor the status of a read. To see the progress indicator in action, try a large file or one from a remote drive.
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);
#progress_bar {
margin: 10px 0;
padding: 3px;
border: 1px solid #000;
font-size: 14px;
clear: both;
opacity: 0;
-moz-transition: opacity 1s linear;
-o-transition: opacity 1s linear;
-webkit-transition: opacity 1s linear;
}
#progress_bar.loading {
opacity: 1.0;
}
#progress_bar .percent {
background-color: #99ccff;
height: auto;
width: 0;
}
<input type="file" id="files" name="file" />
<button onclick="abortRead();">Cancel read</button>
<div id="progress_bar"><div class="percent">0%</div></div>
Look into ondragover event. You could simply have a inside of a div that is hidden until the ondragover event fires a function that will show the div with the in it, thus letting the user drag and drop the file. Having an onchange declaration on the would let you automatically call a function (such as upload) when a file is added to the input. Make sure that the input allows for multiple files, as you have no control over how many they are going to try and drag into the browser.
This technique works very well, but if you want a binary blob rather than just to put the dragged image in an html img element, you'll need to use the 'fetch' function twice.