JavaScript : onchange function causes error/ didn't work - javascript

The Following code will add File upload and preview field.
<b>This single img works but not in js</b> <br>
<img id="img" alt="your image" width="100" height="100" />
<input type="file" onchange="document.getElementById('img').src = window.URL.createObjectURL(this.files[0])">
<br/>
No of Img <input type="text" id="noi" name="noi" value="" onkeyup="addFields()">
<br />
<script>
function addFields(){
// Number of inputs to create
var number = document.getElementById("noi").value;
// Container <div> where dynamic content will be placed
var container = document.getElementById("container");
var array = ["CRICTICAL","HIGH","LOW","INFO"];
// Clear previous contents of the container
while (container.hasChildNodes()) {
container.removeChild(container.lastChild);
}
for (i=1;i<=number;i++){
var img = document.createElement("img");
img.width="100";
img.height="100";
img.id="img "+i;
var upload = document.createElement("input");
upload.type="file";
//This part is Not Working_______________
upload.onchange="document.getElementById(img.id).src = window.URL.createObjectURL(this.files[0])";
//________________________________________
container.appendChild(img);
container.appendChild(upload);
container.appendChild(document.createElement("br"));
}
}
</script>
<div id="container"/>
Problem :
Without the Container appendChild function the code works fine, you can see it in the first three lines of code.

You have to run a function inside upload.onchange. Something like this:
upload.onchange= function () {
document.getElementById(img.id).src = window.URL.createObjectURL(this.files[0])
}
Other way to do:
upload.addEventListener('change', function () {
document.getElementById(img.id).src =
window.URL.createObjectURL(this.files[0])
})

Problem Solved
Working Fine.
All image fields can able to preform upload and preview function of 'n' fields.
<b>This single img works but not in js</b> <br>
<img id="img" alt="your image" width="100" height="100" />
<input type="file" onchange="document.getElementById('img').src = window.URL.createObjectURL(this.files[0])">
<br/>
No of Img <input type="text" id="noi" name="noi" value="" onkeyup="addFields()">
<br />
<script>
function addFields(){
// Number of inputs to create
var number = document.getElementById("noi").value;
// Container <div> where dynamic content will be placed
var container = document.getElementById("container");
var array = ["CRICTICAL","HIGH","LOW","INFO"];
// Clear previous contents of the container
while (container.hasChildNodes()) {
container.removeChild(container.lastChild);
}
for (i=1;i<=number;i++){
var img = document.createElement("img");
img.width="100";
img.height="100";
img.id="img "+i;
var upload = document.createElement("input");
upload.type="file";
upload.id="upload "+i;
//Working_______________
upload.onchange=upload.onchange= function () {
var img_id=this.getAttribute('id');
var imgId = img_id.charAt(7) ;
document.getElementById("img "+imgId).src = window.URL.createObjectURL(this.files[0])
}
//________________________________________
container.appendChild(img);
container.appendChild(upload);
container.appendChild(document.createElement("br"));
}
}
</script>
<div id="container"/>

Related

Cloned, file upload and preview issue with Jquery

I have a clone creation command. The id parameter created as clone is as follows (example: id = "myid_1"), increments it by one and makes id = "myid_2". So far there is no problem. That way, each object has a unique ID value, but a simple file upload and preview function within these clones causes my function to malfunction.
I created a simple example on jsfiddle. https://jsfiddle.net/magecode/mbk9ps2x/12/
The problem I understand here is that the id value of the file upload in the onhange event must increase in parallel with the image preview id. For this, I resorted to the attr function and tried to increase the id in parallel, but it never changed.
The code I want to do in the example. The value i is always incrementing but is not added to the cloned object.
<div class="clonable-block" data-toggle="cloner">
<a href="#" id="addrow" class="btn btn-info btn-block clonable-button-add" style="border-radius: 0px; font-size: 13px;">
<i class="fa fa-file pr-2"></i>Add Row</a>
<div class="clonable">
<br/>
<br/>
<img id="upload_1" alt="your image" width="100" height="100" class="clonable-increment-id" />
<input type="file" id="preview_1"
onchange="document.getElementById('upload_1').src = window.URL.createObjectURL(this.files[0])">
<br/>
<br/>
</div>
</div>
var i = 1;
$("#addrow").click(function () {
i++;
$("#upload_" + i+"").attr("onchange", "document.getElementById('preview_'+ i + '').src = window.URL.createObjectURL(this.files[0])");
});
I recreated this with vanilla.js, you can then transform it to Jquery.
The thing is that it could be much easier. I recommend you vanilla.js, it has a better overall performance, but i understand the simplicity of Jquery.
Here it goes:
const CloneSource = document.querySelector(".clonable-source");
const buttonRow = document.getElementById("add_row");
const clonesContainer = document.getElementById("clones");
let globalCounter = 1; // Create a globalCounter for the Form IDs
window.addEventListener("change", function(e) {
let target = e.target
// This try catch is just for strictly saying that we
// want to target the .clonable class
try {
let form = target.closest(".clonable")
let fd = new FormData(form)
let img = fd.get("img");
let preview = form.children[0]
let url = URL.createObjectURL(img)
preview.setAttribute("src", url);
} catch {
console.log("No Form")
}
})
buttonRow.addEventListener("click", function(e) {
// Creates Form, img, and input elements
let formSource = document.getElementById("source")
let Form = document.createElement("form")
let Img = document.createElement("img")
let Input = document.createElement("input")
Form.className = `clonable clonable-clone`
Form.setAttribute("id", `clonable-${globalCounter}`) // This add the ID to the Form
globalCounter++; // Sum 1 to the globalCounter;
Img.setAttribute("src", formSource.children[0].getAttribute("src"))
Input.setAttribute("type", "file")
Input.setAttribute("name", "img")
Form.appendChild(Img)
Form.appendChild(Input)
// Then append the form to the clones container
clonesContainer.appendChild(Form);
});
img {
width: 5rem;
}
<button id="add_row">Add Row</button>
<div id="clones">
<form class="clonable clonable-source" id="source">
<img src="#">
<input type="file" name="img">
<p>Select an Image</p>
</form>
</div>

Display image from a given url

I have an array with 3 cells.At the first cell i have a textarea where you can insert the url of an image.At the second cell i have a button which when you click the image display at the third cell where i have a div to display the image.The question is how can i display the image either from the internet either from local?
The code i wrote is:
function loadImage(){
var mydiv = document.getElementById("idofdivtodisplayimg");
var url = document.getElementById("idoftextareawhereyouputtheurl");
mydiv.innerHTML = url.value;
}
<html>
<body>
<input type="text" id="imagename" value="" />
<input type="button" id="btn" value="GO" />
<script type="text/javascript">
document.getElementById('btn').onclick = function() {
img = document.createElement('img');
img.src = document.getElementById('imagename').value;
document.body.appendChild(img);
}
</script>
</body>
</html>
You can see the sample code will add the images from an array to the document.
You could also append the images to any of the elements in your function by using url.appendChild
var arr = ['http://via.placeholder.com/350x150', 'http://via.placeholder.com/350x250','http://via.placeholder.com/350x350']; // hold image urls in an array.
arr.forEach(function(item){
// loop through array and add images to the document.
var img = new Image();
img.src = item;
document.body.appendChild(img);
});
In order to do both you would need to change your html and code.
For the case when the user has a url you can just create a new image and append it to your div setting the image's src to the url that was set in the input:
function loadImage(){
var mydiv = document.getElementById("idofdivtodisplayimg");
var url = document.getElementById("idoftextareawhereyouputtheurl");
var image = new Image;
mydiv.appendChild(image);
image.src = url.value;
}
Now to get it to display a local image you will need a file input or a drag and drop scheme as you cannot access local files without some type of user interaction.
So you would, for example, need to change your html to include a file input, and grab a reference to the selected file the user selects. Then use FileReader to read the file, and finally display it
HTML
<input type="file" id="imagefile">
JS
//input reference
var imageinput = document.getElementById("imagefile");
imageinput.addEventListener('change',function (){
var mydiv = document.getElementById("idofdivtodisplayimg");
var image = new Image;
mydiv.appendChild(image);
//FileReader instance
var reader = new FileReader;
reader.addEventListener('load',function(){
//reader.result will contain a dataURL that can be used
//like a regular image url
image.src = reader.result;
});
//read the file as a dataURL
reader.readAsDataURL( imageinput.files[0] );
});
This does both, it let's you upload an image (or at least load it to the browser) or give a URL to an image source. Click the button and the image is loaded and displayed!
This snippet uses the FileReader API to get the uploaded image and display it in an image element
function uploadOrNot() {
if (document.querySelector("input[type=file]").files[0]){
let input = document.querySelector("input[type=file]");
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
display(e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
} else if (document.querySelector("input[type=text]").value){
display(document.querySelector("input[type=text]").value);
}
}
function display(res) {
let img = document.createElement("IMG");
img.src=res;
document.querySelector("#result").appendChild(img);
}
<div id="urlOrUpload">
<input type="text"/>
<br>
<input type="file" accetp="image/*"/>
</div>
<div id="buttonHolder">
<button type="button" onclick="uploadOrNot()">Display</button>
</div>
<div id="result"></div>
I partly solved it by replacing the div at the third cell with an img tag and at the function i wrote above, i chenged it to:
var image = document.getElementbyId("imageid");
var url = document.getElementbyId("urlid");
image.src = url.value;
But at the table i have,i also have a button where you can add a same row as above.How can i do this function for every url that is placed at every textbox?

Jquery closest and find doesn't seem to work

These are my codes. I can't get my jquery code to work.
HTML:
<div class="col-lg-6 col-md-6 col-sm-6">
<input name="hImage" class="form-control" type="file" id="headerImage" required>
<img src="" id="img_url" alt="your image" class="img-responsive">
</div>
JQUERY:
function readURL(e){
if (this.files && this.files[0]){
var reader = new FileReader();
$(reader).load(function(e) {
imagePrev = e.target.result;
var imgElement = $(this).closest('div').find('img');
imgElement.attr('src', imagePrev);
});
reader.readAsDataURL(this.files[0]);
};
I trigger the function with this code:
$("#headerImage").change(readURL);
imagePrev is a base64 data. Which works because when I try
$("#img_url").attr('src', imagePrev);
the image gets loaded.
But I want to use the .closest or .find or .siblings or whatever code is necessary so I can find the nearest img tag and replace its src attr.
The problem is with the this variable, once the execution comes inside the $(reader).load(), the value changes for this variable.
Use the following.
function readURL(e){
$this = $(this);
if (this.files && this.files[0]){
var reader = new FileReader();
$(reader).load(function(e) {
imagePrev = e.target.result;
var imgElement = $this.siblings('img');
imgElement.attr('src', imagePrev);
});
reader.readAsDataURL($this[0].files[0]);
}
};

Multiple class Get each value

How can I get value of textbox appended with image tag. There is list of images with class="hi" and textbox with class multiple.
<div id="images">
<img src="www.xyz.com/qwert.jpg" class="hi">
<input type="text" class="multiple">
<img src="www.xyz.com/qwerty.jpg" class="hi">
<input type="text" class="multiple">
<img src="www.xyz.com/qwertww.jpg" class="hi">
<input type="text" class="multiple">
</div>
How can I get src and value of textbox ?
Script I tried:
var values = "";
$(".hi, .multiple").each(function () {
imageURI = $(this).attr('src'); // I am getting imageURI
???? //How can I get texbox value?
});
$(".hi").each(function () {
var imageURI = $(this).attr('src');
var textBoxVal = $(this).next().val();
});
$(".hi").each(function () {
var imageURI = $(this).attr('src');
var textBoxVal = $(this).next('input').val();
});
Try this:
var values = "";
$(".hi, .multiple").each(function () {
imageURI = $(this).attr('src'); // I am getting imageURI
textBoxVal = $(this).val();
});)

Image upload script to be more dynamic

I have a working script that shows a preview of a image a user is wanting to upload which works fine for a single image upload. I now what to use this script on a multiple image upload and would like to have the readURL function in the script work dynamically so I don't have to repeat the lines
$("#patient_pic1").live("change",function(){
readURL(this, "#preview_image1")
});
for every upload container
here is my html
<div class="upload-file-container"> <img id="preview_image1" class="preimg" src="#" alt="" />
<input type="file" id="patient_pic1" name="pic[]" class="photo" />
</div>
<div class="upload-file-container"> <img id="preview_image2" class="preimg" src="#" alt="" />
<input type="file" id="patient_pic2" name="pic[]" class="photo" />
</div>
and the Jquery
function readURL(input, target) {
if (input.files && input.files[0]) {
var reader = new FileReader();
var image_target = $(target);
reader.onload = function (e) {
image_target.attr('src', e.target.result).show();
};
reader.readAsDataURL(input.files[0]);
}
}
$("#patient_pic1").live("change",function(){
readURL(this, "#preview_image1")
});
$("#patient_pic2").live("change",function(){
readURL(this, "#preview_image2")
});
http://jsfiddle.net/6j1kr549/1/
You can do it like:
$('input[type="file"]').on("change",function(){
var target = '#'+$(this).parent().find('img').attr('id');
readURL(this, target);
});
WORKING DEMO
You should use the each() funtion to loop all classes with a same name and get the input controls for each element inside the class:
PD: Counter is For clarification, but is funtional:
var counter = 1;
$('.upload-file-container').each(function() {
$(this, "#patient_pic" + counter.toString()).live("change",function(){
readURL(this, "#preview_image" + counter.toString())
});
counter = counter + 1;
});

Categories

Resources