Note:I'm new to javascript.
I have the following code which allows the user to preview an image before uploading it.
The input element works fine and the selected image is displayed as expected.
However, the drag and drop throws an error that,
Uncaught TypeError: Cannot read property 'files' of undefined
I think I am taking the dropped file object in a wrong way any help would be greatly appreciated.
(function($){
$(document).ready(function(){
function renderImage(file)
{
var reader = new FileReader();
reader.onload = function(event) {
the_url = event.target.result
$('#preview').html("<img width='150px' height = '100px'src='" + the_url + "' />")
}
reader.readAsDataURL(file);
}
//This is for the input and works fine.
$('#file').change( function (){
renderImage(this.files[0])
});
//The drag is the one with problem.
//it produces the following error
/*
*Uncaught TypeError: Cannot read property 'files' of undefined
*/
$("#drop").on('dragenter', function (e){
e.preventDefault();
$(this).css('background', '#BBD5B8');
});
$("#drop").on('dragover', function (e){
e.preventDefault();
});
$("#drop").on('drop', function (e){
$(this).css('background', '#D8F9D3');
e.stopPropagation();
e.preventDefault();
var dt = e.target.files || (e.dataTransfer && e.dataTransfer.files);
var files = dt.files;
renderImage(files);
});
});
})(jQuery)
#drop
{
width:300px;
height:100px;
border:dotted 1px;
border-radius:5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id = "upload">
<div id = "drop">
</div>
<input type ="file" id = "file">
<div id = "preview">
</div>
</div>
My proposal is, where I corrected also the "Uncaught TypeError: Cannot read property 'files' of undefined" (only for FF it's necessary to double the input field):
(function($){
$(document).ready(function() {
function renderImage(file)
{
var reader = new FileReader();
reader.onload = function(event) {
the_url = event.target.result
$('#preview').html("<img width='150px' height = '100px'src='" + the_url + "' />")
}
reader.readAsDataURL(file);
}
//This is for the input and works fine.
$('input[type^="file"]').change( function (){
renderImage(this.files[0])
});
//The drag is the one with problem.
//it produces the following error
/*
*Uncaught TypeError: Cannot read property 'files' of undefined
*/
$("#drop").on('dragenter', function (e){
event.target.style.background = '#BBD5B8';
});
$("#drop").on('dragover', function (e){
e.preventDefault();
});
$("#drop").on('drop', function (e){
event.target.style.background = '#D8F9D3';
e.stopPropagation();
e.preventDefault();
var dt = (e.originalEvent.target.files && e.originalEvent.target.files.length > 0) || (e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files);
var files = dt[0];
renderImage(files);
});
});
})(jQuery);
#drop
{
width:300px;
height:100px;
border:dotted 1px;
border-radius:5px;
}
#drop input {
position: absolute;
top: 0;
right: 0;
cursor: pointer;
opacity: 0.0;
filter: alpha(opacity=0);
font-size: 300px;
height: 100px;
}
#drop label {
position: absolute;
top: 40px;
width: 250px;
text-align: center;
}
<script src="http://code.jquery.com/jquery-1.11.3.js"></script>
<div id="upload">
<div id="drop">
<label id="fileLbl">Drop a file here</label>
<input type ="file" id = "file1">
</div>
<input type ="file" id = "file2">
<div id = "preview">
</div>
</div>
I believe the issue is with your HTML. Try moving your input inside of your #drop div
<div id = "upload">
<div id = "drop">
<input type ="file" id = "file">
</div>
<div id = "preview">
</div>
</div>
Related
I am looking for help to customise the code when onclick in the input field type open flmngr window + selecting the file and adding to the input field the URL of the file selected
window.onFlmngrAndImgPenLoaded = function() {
var elBtn = document.getElementById("btn");
// Style button as ready to be pressed
elBtn.style.opacity = 1;
elBtn.style.cursor = "pointer";
var elLoading = document.getElementById("loading");
elLoading.parentElement.removeChild(elLoading);
// Add a listener for selecting files
elBtn.addEventListener("click", function() {
selectFiles();
});
}
function selectFiles() {
let flmngr = window.flmngr.create({
urlFileManager: 'https://fm.n1ed.com/fileManager',
urlFiles: 'https://fm.n1ed.com/files'
});
flmngr.pickFiles({
isMultiple: false,
acceptExtensions: ["png", "jpeg", "jpg", "webp", "gif"],
onFinish: function(files) {
showSelectedImage(files);
}
});
}
function showSelectedImage(files) {
let elImages = document.getElementById("images");
elImages.innerHTML = "";
var file = files[0];
let el = document.createElement("div");
el.className = "image";
elImages.appendChild(el);
let elImg = document.createElement("img");
elImg.src = file.url;
elImg.alt = "Image selected in Flmngr";
el.appendChild(elImg);
let elP = document.createElement("p");
elP.textContent = file.url;
el.appendChild(elP);
}
body {
padding: 20px;
background-color: #F4F4F4;
}
#images {
.image {
border: 1px solid #DDD;
box-shadow: 5px 5px 0 0 #DDD;
background-color: white;
padding: 10px;
display: inline-flex;
flex-direction: column;
margin: 0 25px 25px 0;
img {
max-height: 350px;
border: 1px solid #DDD;
}
p {
margin: 5px 0 0 0;
font-size: 14px;
color: #444;
}
}
}
<h1 class="h5 mb-3">Flmngr file manager: select a single image</h1>
<div id="btn" class="btn btn-primary" style="opacity:0.2;cursor:default">Select image...</div>
<div id="loading" style="font-size:12px">Loading file manager...</div>
<h2 class="h5 mt-5">Selected image</h2>
<div id="images">
No image selected yet.
</div>
<script src="https://cloud.flmngr.com/cdn/FLMNFLMN/flmngr.js"></script>
<script src="https://cloud.flmngr.com/cdn/FLMNFLMN/imgpen.js"></script>
I am looking for something like this clicking on the input field open the flmngr file manager, clicking or selecting the file, populate the URL of the file to the input field
<input type="text" name="field_name" id="field_name" value="https://fm.n1ed.com/files/book.png" onclick="BrowseServer('field_name');">
I really appreciate any help.
Thank you
Best Regards
I found a solution to click on the input
window.onFlmngrAndImgPenLoaded = function() {
var elBtn = document.getElementById("FlmngrBrowseServer");
// Style button as ready to be pressed
elBtn.style.opacity = 1;
elBtn.style.cursor = "pointer";
var elLoading = document.getElementById("loadingFlmngrBrowseServer");
elLoading.parentElement.removeChild(elLoading);
// Add a listener for selecting files
elBtn.addEventListener("click", function() {
selectFiles();
});
}
function selectFiles() {
let flmngr = window.flmngr.create({
urlFileManager: 'https://fm.n1ed.com/fileManager',
urlFiles: 'https://fm.n1ed.com/files'
});
flmngr.pickFiles({
isMultiple: false,
acceptExtensions: ["png", "jpeg", "jpg", "webp", "gif"],
onFinish: function(files) {
showSelectedImage(files);
}
});
}
function showSelectedImage(files) {
var file = files[0];
var x = file.url;
document.getElementById("FlmngrBrowseServer").value = x;
}
<input type="text" name="configuration[MODULE_PAYMENT_BTC_IMAGE]" value="images/payment_bitcoin.png" id="FlmngrBrowseServer">
<div id="loadingFlmngrBrowseServer"></div>
<input type="text" name="configuration[MODULE_PAYMENT_BTC_IMAGE]" value="images/payment_bitcoin.png" id="FlmngrBrowseServer1">
<div id="loadingFlmngrBrowseServer1"></div>
<script src="https://cloud.flmngr.com/cdn/FLMNFLMN/flmngr.js"></script>
<script src="https://cloud.flmngr.com/cdn/FLMNFLMN/imgpen.js"></script>
field and select the file then get the URL link and parse to the input field, but I need a solution for 2 or more input fields.
I'm working on uploading multiple images one at a time by dynamically generating the input field and image element. However, my code doesn't display the images on the dynamically generated image element.
<button type="button" class="btn btn-sm btn-info add-image"><i class="ti-image"></i> Add image</button>
<br><br>
<div class="images"></div>
$(document).ready(function() {
var max_image = 10;
var count = 1;
$('.add-image').click(function(e) {
e.preventDefault();
if (count < max_image) {
count++;
$('.images').append(`<div class="input" style="width:100px;height:120px;border:2px dashed lightgrey;float:left;margin:8px">
<input type ="file" class ="fileup 1" id ="file'+count+'" style="width:100%; height:100%; opacity:0; position: absolute">
<img id ="image'+count+'" src="" style="width:100%; height:100%;">
<span class="btn btn-sm btn-danger delete" style="position:relative;bottom:20px"><I class="ti-trash"></i></span>
</div>`);
$(document).on('change', '#file' + count, function() {
readURL(this);
});
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$('#image' + count).attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
} else {
alert("Only a maximum of 10 images is allowed");
}
});
$('.images').on("click", ".delete", function(e) {
e.preventDefault();
$(this).parent('div').remove();
y--;
})
});
Instead of making event handler for all files use can just one event handler and then inside your readURL function use .closest('div').find('img') to add src to image tag.
Demo Code :
$(document).ready(function() {
// allowed maximum input fields
var max_image = 10;
// initialize the counter for textbox
var count = 1;
// handle click event on Add More button
$('.add-image').click(function(e) {
e.preventDefault();
if (count < max_image) {
count++; // increment the counter
// validate the condition
$('.images').append(`<div class="input" style="width:100px;height:120px;border:2px dashed lightgrey;float:left;margin:8px">
<input type ="file" class ="fileup 1" id ="file'+count+'" style="width:100%; height:100%; opacity:0; position: absolute">
<img id ="image'+count+'" src="" style="width:100%; height:100%;">
<span class="btn btn-sm btn-danger delete" style="position:relative;bottom:20px"><I class="ti-trash"></i></span>
</div>`); // add input field
} else {
alert("Only a maximum of 10 images is allowed");
}
});
// handle click event of the remove link
$('.images').on("click", ".delete", function(e) {
e.preventDefault();
$(this).parent('div').remove(); // remove input field
y--; // decrement the counter
})
//put this outside..
$(document).on('change', '.images input[type=file]', function() {
readURL(this);
});
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
//get closest div and then find img add img there
$(input).closest('div').find('img').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" class="btn btn-sm btn-info add-image"><i class="ti-image"></i> Add image</button>
<br><br>
<div class="images"></div>
There's several issues to address here.
Don't nest your event handlers
Put CSS rules in an external stylesheet, not inline in the HTML
You're not appending the count value to the template literal using the correct syntax
Aside from the above, do not use incremental id attributes. Group elements with common behaviour by class and attach a single event handler to them all. This is what you should do with the delegated event handler you're using.
The latter point is what fixes your issue, as it will allow you to target the img which was clicked on and update its specific src attribute to the content of the file which was selected.
$(document).ready(function() {
var max_image = 10;
$(document).on('change', '.fileup', function() {
readURL(this, $(this).next('img'));
});
function readURL(input, $target) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$target.attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$('.add-image').click(function(e) {
e.preventDefault();
if ($('div.input').length < max_image) {
$('.images').append(`<div class="input">
<input type="file" class="fileup" />
<img />
<span class="btn btn-sm btn-danger delete">
<i class="ti-trash">X</i>
</span>
</div>`);
} else {
alert("Only a maximum of 10 images is allowed");
}
});
$('.images').on("click", ".delete", function(e) {
e.preventDefault();
$(this).closest('div').remove();
})
});
div.input {
width: 100px;
height: 120px;
border: 2px dashed lightgrey;
float: left;
margin: 8px;
}
input.fileup {
width: 100%;
height: 100%;
opacity: 0;
position: absolute;
}
div.input img {
width: 100%;
height: 100%;
}
span.delete {
position: relative;
bottom: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" class="btn btn-sm btn-info add-image">
<i class="ti-image"></i>
Add image
</button>
<br><br>
<div class="images"></div>
Hi i have an image upload form , and when selecting upload the image it will show the preview also.
$( function() {
var inputLocalFont = document.getElementById("user_file");
inputLocalFont.addEventListener("change",previewImages,false);
function previewImages(){
var fileList = this.files;
var anyWindow = window.URL || window.webkitURL;
for(var i = 0; i < fileList.length; i++){
var objectUrl = anyWindow.createObjectURL(fileList[i]);
$('.new-multiple').append('<div class="img-div"><img src="' + objectUrl + '" class="newly-added" /></div>');
window.URL.revokeObjectURL(fileList[i]);
}
$( ".img-div" ).draggable();
$( ".img-div" ).resizable();
$(".newly-added").on("click", function(e) {
$(".newly-added").removeClass("img-selected");
$(this).addClass("img-selected");
e.stopPropagation();
});
$(document).on("click", function(e) {
if ($(e.target).is(".newly-added") === false) {
$(".newly-added").removeClass("img-selected");
}
});
}
});
.new-multiple {
width:400px !important;
height:400px !important;
background:white;
border:2px solid red;
overflow:hidden;
}
.img-div {
width:200px;
height:200px;
}
.newly-added {
width:100%;
height:100%;
}
.img-selected{
box-shadow: 1px 2px 6px 6px rgb(206, 206, 206);
}
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<input name="user_file[]" id="user_file" style="position: relative;overflow: hidden" multiple="" type="file">
<div class="new-multiple"></div>
I write both resizable, draggable function for the images .
so here when I click on selected img and press delete button on keyboard I need to delete that image . If press undo through keyboard I have to get it back . How can I achieve this
I see jQuery. Hotkeys , https://github.com/jeresig/jquery.hotkeys
and I write the following code . but it is not working
$('.img-selected').bind('del', '$', function(){
alert("yes");
});
Please check this
https://jsfiddle.net/vd11qyzv/7/
UPDATED FIDDLE
Please check this https://jsfiddle.net/vd11qyzv/9/ . Here
if ($(e.target).is(".newly-added") === true) { alert('abc'); } is not working.
The keyboard event is not going to img-selected object.
Until now for keyboard handling I used this format and worked well.
$(document).on('keydown', handleKeyDown);
function handleKeyDown(e){
if(e.keyCode === 46)//delete Key{
deleteActiveObject();
}
}
Hope this helps you.
I am trying to create some code to work. However, I keep getting errors, and I have been stuck with this for a while now and in need of help. Whenever the image gets an attempt to be added to the page, I get:
<undefined src='(this is where the filepath is listed)'><undefined>
Why are the tags not coming out as div?
Css Code:
.clock{
background-image:url('');
background-size:cover;
background-position: center;
height: 250px; width: 250px;
border: 1px solid #bbb;
}
#myUL{
height: 1000px;
width: 1000px;
}
Html Code:
<input type='file' id='getval' />
<span onclick="readURL()" class="addBtn">Add</span>
<div class='clock'></div>
<div id='myUL'></div>
Script code:
function readURL(){
var file = document.getElementById("getval").files[0];
var reader = new FileReader();
reader.onloadend = function(){
var div = document.createElement(div);
div.setAttribute("src", "url(" + reader.result + ")");
div.class = 'clock';
document.getElementById('myUL').appendChild(div);
}
if(file){
reader.readAsDataURL(file);
}else{}
}
var div = document.createElement(div); // <<< (div) is a variant.
see https://jsfiddle.net/3L53bzx5/1/
reader.onloadend = function() {
var img = document.createElement('img');
img.setAttribute("src", reader.result);
img.className = 'clock';
document.getElementById('myUL').appendChild(img);
}
You have to change below line
var div = document.createElement(div);
to
var div = document.createElement('div');
in your readURL() method.
I want to upload an image by clicking on the image element with id='IBrowse' but an error occurs when I click on the that image.
Cannot read property 'target' of undefined(…) (in Chrome)
TypeError: event is undefined (in Firefox)
<div class="col-md-12 col-sm-12 col-xs-12 form-group has-feedback pull-right bordered">
<img id="HImg" src="~/b/b.jpg" style="height: 120px; max-width: 100%; width: 280px; position:relative", class="img-responsive" />
<img id="IBrowse" src="~/a/a.png" style="position: absolute; width: 20%; top: 5%; left: 17%;" />
#Html.TextBoxFor(m => m.Img, new { #class = "form-control has-feedback-left file btntag", style = "display: none;", #onchange = "open(e)", #type = "file", placeholder = "Upload Image" })
#Html.ValidationMessageFor(m => m.Img, "", new { #class = "text-danger" })
</div>
$(function () {
$('#IBrowse').on('click', function () {
$('#Img').trigger('onchange');
});
});
onchange event code
<script>
var IsUpdate = false;
var open = function (event) {
var input = event.target;
var reader = new FileReader();
reader.onload = function () {
var dataURL = reader.result;
var output = document.getElementById('ImgHTMLElement');
output.src = dataURL;
};
reader.readAsDataURL(input.files[0]);
};
</script>
Also, the CSS is not working:
#IBrowse:hover {
width: 23%;
}
I never use onchange so maybe there is a way to do this there. However, I would simply drop the onchange="....." and use a handler like this:
<script>
var IsUpdate = false;
$('#Img').on('change', function(event) {
var input = event.target;
var reader = new FileReader();
reader.onload = function() {
var dataURL = reader.result;
var output = document.getElementById('ImgHTMLElement');
output.src = dataURL;
};
reader.readAsDataURL(input.files[0]);
});
</script>
As for your css issue, the problem is that you define an inline style like:
<img id="HImg" src="~/b/b.jpg" style="height: 120px; max-width: 100%; width: 280px; position:relative", class="img-responsive" />
The css rule #IBrowse:hover {width: 23%;} is applied, but it will not override the inline style setting which has a higher precedence. You can overcome that by
Option 1) Preferred method
Move your inline style to a css rule instead of inline like this:
#IBrowse{
position: absolute;
width: 20%;
top: 5%;
left: 17%;
}
#IBrowse:hover {
width: 23%;
}
jsFiddle example
Option 2)
Leave the inline style and add !important to the hover css rule like this:
#IBrowse:hover {
width: 23% !important;
}
jsFiddle example
I haven't tested your code but if you want your open function to be passed the event object you should specify it as event rather than e in the onchange attribute definition, since this is not an assignment to the the event itself, but a callback function body that already has been passed the event parameter:
#onchange = "open(event)"