I have a field which is upload image images but the problem is this field has add row functionality with the help of append function. What I want to show the image preview on select of the image in each added row so, please tell me how I can do this.
view page-
jQuery(document).ready(function() {
$("#append").click(function(e) {
e.preventDefault();
$(".inc").append('<div class="controls">\
<input name="product_image[]" id="product_image" class="form-control" type="file">\
Remove\<div class="col-sm-10 col-sm-offset-2" style="margin-top: 10px;"><img src="" class="imgpre" id="imgPrev" style="width: 200px; height: 150px; border: 1px solid #ddd" ></div><br>\
<br>\
</div>');
return false;
});
jQuery(document).on('click', '.remove_this', function() {
jQuery(this).parent().remove();
return false;
});
$("input[type=submit]").click(function(e) {
e.preventDefault();
$.map($(".inc :text"), function(el) {
return el.value
}).join(",\n")
})
});
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$('#imgPrev').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#product_image").change(function() {
readURL(this);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group">
<label class="col-sm-2 control-label" for="parentId">Image</label>
<div class="col-sm-6 inc">
<input name="product_image[]" id="product_image" class="form-control" type="file"> <button style="margin-left: 50px; position:relative;left:575px;top:-31px;" class="btn btn-info" type="submit" id="append" name="append">
Add</button>
<br>
<br>
</div>
<div class="col-sm-10 col-sm-offset-2" style="margin-top: 10px;">
<img src="" class="imgPrev" id="imgPrev" style="width: 200px; height: 150px; border: 1px solid #ddd">
</div>
</div>
Starting with your code (but modified, separated CSS etc.) I came up with this quick solution :
$(document).on("change", "input.form-control", function() {
readURL(this);
});
const readURL = input => {
if (input.files && input.files[0]) {
let reader = new FileReader();
reader.onload = e => {
$(input)
.siblings("img")
.attr("src", e.target.result);
};
reader.readAsDataURL(input.files[0]);
}
};
$("#append")
.click(() => {
$(".form-group").append(`
<div class="row">
<input class="form-control" type="file">
<br>
<img src="" class="imgPrev">
<button class="remove">Remove</button>
</div>
`);
})
.trigger("click");
$(document).on("click", "button.remove", function() {
$(this).parent().remove();
return false;
});
.btn-add {
margin-left: 50px;
position: relative;
left: 200px;
}
.row {
margin-bottom: 20px;
}
.row .imgPrev {
width: 200px;
height: 150px;
border: 1px solid #ddd;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group">
<button class="btn btn-add" id="append">Add</button>
</div>
Related
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>
I have simple div with one element:
<div id="drop-zone">
<input type="file" style="display: none;" multiple="multiple">
</div>
When I click on #drop-zone I want to trigger input manually. I'm trying like this:
jQuery('#drop-zone:not(input)').click(function() {
jQuery(this).find('input[type="file"]').trigger('click')
})
The main problem is that I'm getting an endless loop of clicks as my manual click trigger listener on parent element.
Make sure that the element clicked was the drop-zone by checking the id of the target. When jQuery emulates an event it will pass the same this reference but will not pass the event, so just check if the event is set.
$("#drop-zone").click(function(event) {
if (this.id === "drop-zone" && event.originalEvent) {
$("#drop-zone>input").trigger("click");
}
})
#drop-zone {
background-color: red;
height: 50px;
width: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="drop-zone">
<input type="file" style="display: none;" multiple="multiple">
</div>
You could also just trigger the event manually.
$("#drop-zone").click(function(event) {
if (this.id === "drop-zone") {
$("#drop-zone>input")[0].click();
}
})
#drop-zone {
background-color: red;
height: 50px;
width: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="drop-zone">
<input type="file" style="display: none;" multiple="multiple">
</div>
Maybe this is what you want:
var x_m = 0;
var y_m = 0;
$('#drop-zone').click(function(event) {
var mtarget = document.elementFromPoint(x_m, y_m);
if (mtarget.id === "drop-zone") {
var input = $(this).find('input[type="file"]');
var h = false;
if ($(input).is(":visible")) {
input.hide();
} else {
input.show();
h = true;
}
console.log("You clicking, the #drop-zone, input.visible =>", h);
} else {
console.log("You clicking the input.");
}
})
$('body').mousemove(function(evt){
x_m = evt.pageX;
y_m = evt.pageY;
});
#drop-zone {
height: 40px;
width: 250px;
background-color: #8b5fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="drop-zone">
<input type="file" style="display: none; background: green;" multiple="multiple">
</div>
I'm trying to upload a second img to the cropper that populates the second .img-result. The cropper should populae whatever was uploaded, and then when the save btn is pressed, the .img-result is updated.
I added the attribute data-up but I'm not sure how to call it in the JS.
// vars
var result = document.querySelector('.result'),
img_result = document.querySelector('.img-result'),
img_w = document.querySelector('.img-w'),
img_h = document.querySelector('.img-h'),
options = document.querySelector('.options'),
save = document.querySelector('.save'),
cropped = document.querySelector('.cropped'),
upload = document.querySelector('.file'),
cropper = '';
// on change show image with crop options
upload.addEventListener('change', function(e) {
if (e.target.files.length) {
// start file reader
var reader = new FileReader();
reader.onload = function(e) {
if (e.target.result) {
// create new image
var img = document.createElement('img');
img.id = 'image';
img.src = e.target.result;
// clean result before
result.innerHTML = '';
// append new image
result.appendChild(img);
// init cropper
cropper = new Cropper(img);
}
};
reader.readAsDataURL(e.target.files[0]);
}
});
// save on click
save.addEventListener('click', function(e) {
e.preventDefault();
// get result to data uri
var imgSrc = cropper.getCroppedCanvas({
width: img_w.value // input value
}).toDataURL();
// show image cropped
cropped.src = imgSrc;
});
.img-result {
border: 2px solid;
width: 50px;
height: 50px;
}
.img-result img {
max-height: 100%;
max-width: 100%;
}
.page {
display: flex;
align-items: flex-start;
flex-wrap: wrap;
height: 100%;
}
.result {
display: flex;
}
.box {
padding: 0.5em;
width: 100%;
margin: 0.5em;
}
.box-2 {
padding: 0.5em;
width: calc(100%/2 - 1em);
}
.img-w {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/0.8.1/cropper.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/cropper/2.3.4/cropper.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<main class="page">
<div class="box">
<div class="options">
<input type="number" class="img-w" value="300" min="100" max="1200" />
</div>
<button class="btn save">Save</button>
</div>
<div class="box">
<input class="file" type="file" id="file-input" data-up="1">
</div>
<div class="box">
<input class="file" type="file" id="file-input" data-up="2">
</div>
<div class="box-2">
<div class="result"></div>
</div>
<div class="result">
<div class="box-2 img-result">
<img class="cropped" src="" alt="" data-up="1">
</div>
<div class="box-2 img-result">
<img class="cropped" src="" alt="" data-up="2">
</div>
</div>
</main>
First of all, as I mentioned in comments. Id must be for each element of your DOM. So, you better change id="file-input" to id="file-input1" and so on.
And It looks like you want to get the attribute value data-up when save function called,
You can do that in this way
save.addEventListener('click', function(e) {
e.preventDefault();
// get result to data uri
document.getElementById('file-input1).getAttribute('data-up')
....
I want to make a webpage that adds points when you click on it. There is a sidebar(just a left column) where there are images that act as checkboxes. Selecting one image gets you 1 point when you click on the page, selecting the other gives 5...
However, I don't want to have the sidebar give points. It means that when you click on it, it only changes the selected image, without adding points. Everything is working except the "not adding points on the sidebar" part. I tried the following code, but it doesn't work:
function addPoint(number) {
points = points + number;
document.getElementById('points').innerHTML = points;
};
function pointsAmount() {
chkBox1 = document.getElementById('picture1').checked;
addPoint(chkBox1 ? 1 : 0);
chkBox2 = document.getElementById('picture2').checked;
addPoint(chkBox2 ? 5 : 0);
chkBox3 = document.getElementById('picture3').checked;
addPoint(chkBox3 ? 10 : 0);
chkBox4 = document.getElementById('picture4').checked;
addPoint(chkBox4 ? 20 : 0);
};
function checkPicture(x, y) {
document.getElementById(x).checked = y;
}
function Border(x, y) {
document.getElementById(x).style.borderColor = y;
}
function onPageload() {
checkPicture('picture1', true);
Border('pic1', 'yellow');
}
window.onload = onPageload;
window.onmousedown = function(e) {
if (e.target.className != 'float-left-area') {
pointsAmount();
}
}
var points = 0;
body {
margin-top: 0px;
margin-right: 0px;
margin-left: 0px;
margin-bottom: 0px;
}
input[type=checkbox] {
display: none;
}
input[type=button] {
display: none;
}
.float-left-area {
position: absolute;
width: 20%;
float: left;
background-color: #dddddd;
border: 3px solid black;
height: 99%;
}
.float-right-area {
float: right;
width: 80%;
height: 100%;
}
.inner-left {
font-size: 2em;
}
img.size {
width: 3em;
height: 3em;
}
<div class="float-left-area">
<div class="inner-left">
<label for="picture1"><div id="pic1" style="border: 5px solid black;"><img src="eslcc_logo2.png" alt="eslcc logo" style="float:left;" class="size" /><p align="right">1</p></div></label>
<input id="picture1" type="checkbox" onchange="checkPicture('picture1', true)" onclick="
checkPicture('picture2', false);
checkPicture('picture3', false);
checkPicture('picture4', false);
Border('pic1', 'yellow');
Border('pic2', 'black');
Border('pic3', 'black');
Border('pic4', 'black');" />
<label for="picture2"><div id="pic2" style="border: 5px solid black;"><img src="imac_2.jpg" style="float:left;" class="size" alt="iMac" /><p align="right">5</p></div></label>
<input id="picture2" type="checkbox" onchange="checkPicture('picture2', true)" onclick="
checkPicture('picture1', false);
checkPicture('picture3', false);
checkPicture('picture4', false);
Border('pic2', 'yellow');
Border('pic1', 'black');
Border('pic3', 'black');
Border('pic4', 'black');" />
<label for="picture3"><div id="pic3" style="border: 5px solid black;"><img src="coding_img.png" style="float:left;" class="size" alt="iMac" /><p align="right">10</p></div></label>
<input id="picture3" type="checkbox" onchange="checkPicture('picture3', true)" onclick="
checkPicture('picture1', false);
checkPicture('picture2', false);
checkPicture('picture4', false);
Border('pic3', 'yellow');
Border('pic1', 'black');
Border('pic2', 'black');
Border('pic4', 'black');" />
<label for="picture4"><div id="pic4" style="border: 5px solid black;"><img src="ariane_6.jpg" style="float:left;" class="size" alt="Ariane 6"/><p align="right">20</p></div></label>
<input id="picture4" type="checkbox" onchange="checkPicture('picture4', true)" onclick="
checkPicture('picture1', false);
checkPicture('picture2', false);
checkPicture('picture3', false);
Border('pic4', 'yellow');
Border('pic1', 'black');
Border('pic2', 'black');
Border('pic3', 'black');" />
</div>
</div>
<div class="float-right-area">
<div class="inner-right">
<p align="center">Points: <span id="points">0</span></p>
Also, no jQuery please.
Not sure if this is what you want:
I remove the bulky code in the checkbox input and set different values in the attribute (i.e. value, data-pic), then consolidate all actions in the function addPoint(number).
I have also modified function pointsAmount() by using for loop to get the points of selected picture. And points will only be added when you click on the right side area.
function addPoint(number) {
points = points + number;
document.getElementById('points').innerHTML = points;
}
function checkPicture(x, y) {
document.getElementById(x).checked = y;
}
function Border(x, y) {
document.getElementById(x).style.borderColor = y;
}
function selectPicture(selectedPic) {
var checkboxes = document.getElementsByName('picture');
for (var i = 0; i < checkboxes.length; i++)
{
var id = checkboxes[i].id;
var pic = checkboxes[i].getAttribute('data-pic');
// Default state and style
checkPicture(id, false);
Border(pic, 'black');
if (id == selectedPic.id)
{
checkPicture(id, true);
Border(pic, 'yellow');
}
}
}
function pointsAmount() {
var checkboxes = document.getElementsByName('picture');
for (var i = 0; i < checkboxes.length; i++)
{
if (checkboxes[i].checked)
{
var value = parseInt(checkboxes[i].value);
addPoint(value);
}
}
}
function onPageload() {
checkPicture('picture1', true);
Border('pic1', 'yellow');
}
window.onload = onPageload;
window.onmousedown = function(e) {
if (e.target.className == 'float-right-area') {
pointsAmount();
}
}
var points = 0;
<div class="float-left-area">
<div class="inner-left">
<label for="picture1">
<div id="pic1" style="border: 5px solid black;">
<img src="eslcc_logo2.png" alt="eslcc logo" style="float:left;" class="size">
<p align="right">1</p>
</div>
</label>
<input id="picture1" type="checkbox" name="picture" data-pic="pic1" value="1" onclick="selectPicture(this)">
<label for="picture2">
<div id="pic2" style="border: 5px solid black;">
<img src="imac_2.jpg" style="float:left;" class="size" alt="iMac">
<p align="right">5</p>
</div>
</label>
<input id="picture2" type="checkbox" name="picture" data-pic="pic2" value="5" onclick="selectPicture(this)">
<label for="picture3">
<div id="pic3" style="border: 5px solid black;">
<img src="coding_img.png" style="float:left;" class="size" alt="iMac">
<p align="right">10</p>
</div>
</label>
<input id="picture3" type="checkbox" name="picture" data-pic="pic3" value="10" onclick="selectPicture(this)">
<label for="picture4">
<div id="pic4" style="border: 5px solid black;">
<img src="ariane_6.jpg" style="float:left;" class="size" alt="Ariane 6">
<p align="right">20</p>
</div>
</label>
<input id="picture4" type="checkbox" name="picture" data-pic="pic4" value="20" onclick="selectPicture(this)">
</div>
</div>
<div class="float-right-area">
<div class="inner-right">
<p align="center">Points: <span id="points">0</span></p>
</div>
</div>
hello i have an image upload with image preview, when user upload image, a button remove show up for cancel that image(the image user upload) and switch to back to image default(for this case placeholder image), and the button remove got hidden because input file didnt have any value.
for now i success to show up the button when user upload. but when user click the remove. only the button remove got hidden, but the image still there. how to make the image back to placeholder when user click remove?
this is my code
$(document).ready(function() {
$(".input-file").on("change", function(){
if($(this).val() == "") {
$(this).parent().find(".image-upload-footer").css({"display": "none"});
} else {
$(this).parent().find(".image-upload-footer").css({"display": "block"});
}
});
$(".reset").click(function(){
$(this).closest(".image-upload").parent().find(".input-file").val("").trigger('change');
});
});
this is the jsfiddle https://jsfiddle.net/uxsxuwzd/1/
thankyou
Please replace this code in your functions. You should have to reset the selected src of input file.
This is for multiple type of images in dimension.
$(document).ready(function() {
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#image_upload_preview1').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#inputFile1").change(function () {
readURL(this);
});
});
$(document).ready(function() {
function readURLs(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#image_upload_preview2').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#inputFile2").change(function () {
readURLs(this);
});
});
$(document).ready(function() {
$(".input-file").on("change", function(){
if($(this).val() == "") {
$(this).parent().find(".image-upload-footer").css({"display": "none"});
} else {
$(this).parent().find(".image-upload-footer").css({"display": "block"});
}
});
$(".reset").click(function(){
$(this).closest(".image-upload").parent().find(".input-file").val("").trigger('change');
var newImg=$(this).attr('custattr');
$("#"+$(this).closest(".image-upload").parent().find(".img-responsive").attr('id')).attr("src",newImg);
});
});
.image-upload-footer p{
display: inline
}
.image-upload input[type=file]{
display: none;
}
.image-upload label{
margin-bottom: 0;
}
.image-upload img{
cursor: pointer;
}
.profileback .deleteThis{
position: absolute;
top: 6px;
right: 21px;
padding: 0;
}
.deleteThis span{
color: #fff
}
.image-upload-footer{
background-color: rgba(34, 34, 34, 0.87);
margin-top: -6px;
padding: 4px 10px;
}
.image-upload-footer button{
padding: 0px 5px;
border-radius: 100%;
margin-left: 15px;
}
.image-upload-footer button span,.image-upload-footer p{
color: #fff ;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
<div class="col-xs-6">
<div class="image-upload">
<label for="inputFile1">
<img id="image_upload_preview1" class="img-responsive mainPic" src="http://placehold.it/350x150"/>
</label>
<input id="inputFile1" class="input-file" type="file"/>
<div class="image-upload-footer" style="display:none">
<button type="reset" custattr="http://placehold.it/350x150" class="btn btn-red reset">
<span class="fa fa-times"aria-hidden="true">X</span>
</button>
<p>remove</p>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="image-upload">
<label for="inputFile2">
<img id="image_upload_preview2" class="img-responsive" src="http://placehold.it/746x728" alt=""/>
</label>
<input id="inputFile2" class="input-file" type="file"/>
<div class="image-upload-footer" style="display:none">
<button type="button" custattr="http://placehold.it/746x728" class="btn btn-red reset">
<span class="fa fa-times"aria-hidden="true">X</span>
</button>
<p>remove</p>
</div>
</div>
</div>
This is for one type of images dimension
$(".reset").click(function(){
$(this).closest(".image-upload").parent().find(".input-file").val("").trigger('change');
$("#"+$(this).closest(".image-upload").parent().find(".img-responsive").attr('id')).attr("src","http://placehold.it/350x150");
});