• Announcements

    • boen_robot

      Guidelines and Netiquette   03/28/2017

      Posting Problems:   Having problems posting your topic? Read through this: To join, you agree to our terms and conditions and fill out and submit a registration form. An activation email will be sent to your email adress, so you'll need to verify your account. After that the account has to be validated by one of the moderators. This will mean that it can take up to a day to be activated. A couple of things to remember to ensure approval: Don't use an email address in one of those $2 four character .com domains eg. xyds.com. These will be deleted and the domain added to the banned list. Don't use an email address that is within a domain with a bad reputation for spam. A Google search is run on every email address and email domain. Don't sign up with an email address that doesn't exist, doesn't work or requires the sender to answer a quiz before their email can get to you. Put your country and or state and city in the signup form. Blank forms will go to the botton of the "to do" list. And make sure that your email address and your country match, saying you're from Alabama and using a .ru email address is not going to get you activated. After a membership is activated the first few posts will be monitored. Posting spam or unapproved topics described in the agreement results in an immediate ban. The email provider and the IP addresses associated with the account will be banned and all posts will be deleted. These strict measures have been deemed necessary to hinder spam. Sorry for any inconvenience this causes, but it's not liable to change. If, after reading this, you still can't post and don't understand why, contact one of the Moderators listed here.   Topic Guidelines   Including the following information can expedite an accurate response from board members: Must be a Specific Problem or Question related to web design and development Include Code in Question (wrap with   for small blocks of code and for longer blocks   ) Include Code Author Include Extra Notes/Modifications/Attempts Include web link to page/file when possible Content Guidelines   You may not post, upload, link to, or email any Content that contains, promotes, gives instruction about, or provides prohibited Content. Prohibited Content includes any Content that breaks any local, state, county, national or international law. Prohibited Content also includes: No direct or indirect advertising or websites, forums, products, services No hijacking of posts (do not post your question in someone elses) Content that infringes upon any rights [ex. MP3s and ROMs] (including, but not limited to, copyrights and trademarks) Abusive, threatening, defamatory, racist, or obscene Viruses or any other harmful computer software False Information or libel Spam, chain letters, or Pyramid schemes Gambling or Illicit drugs Terrorism Hacking or cheating for internet/online games Warez, Roms, CD-Keys, Cracks, Passwords, or Serial Numbers Pornography, nudity, or sexual material of any kind Excessive profanity Invasive of privacy or impersonation of any person/entity Hacking materials or information Posting Tips   There are more BBcodes than there are buttons for on the reply menu. To get the full list, click "BB Code Help" underneath the clickable smilie face menu. Use   for small snippets of code Use   for lengthy snippets of code Use   if your snippet is HTML (optional) Use   if your snippet is SQL (optional) Rules of Conduct   Be nice. There's no need for calling someone stupid if they ask an 'easy' question. Keep your avatars and signatures absolutely child friendly. We have a younger audience on this forum. Keep your language appropriate for the same reason above. Do not PM moderators for help on the forum. Post on the topic, or create a new one.   Spam:   Recently, as you have all without doubt noticed, we have had lots of spam and advertisement on the forum. Therefore, we'd like to alert you as to what to do when you have found any of the aforementioned annoying messages: it. Immediately. Give a clear reason, please, if the advertising is not evident. DO NOT POST! Report, let the post stay as is, and we will get to it, meanwhile if you continue to post as normal in the other threads, it won't be on the top so long. Refrain from PMing the member. This won't help at all, as they are most likely spambots anyway. Thank you.       Images in signatures:   After thinking of users on dial-up, we have decided to enforce the following rules regarding signatures. Please pay heed to them. Respecting these rules is respecting the members on this forum with dial-up. Signature rules: No animated images AT ALL. No matter the amount of animation. Maximum image widthxheight: 300x150 Maximum image (file) size: 15kb Use calm colors. Do not use highly contrasting images in your signature, as this can get really annoying when seeing several posts from one member in the same thread. The same prohibited content goes for images as for posts. Lastly, use common sense. No lengthy signatures please. Save us some scrolling. Thank you.       Links in signatures:   Please understand that w3schools.com only exists because of voluntary work and is barely supported by the advertising littered throughout the tutorials and the forum. So, please, stop advertising other sites. DO not post links that drive traffic away from the w3schools domain - especially to a site that offers similar if not identical information. Please help support the site by keeping individuals on it. Thank you. Here are some guidelines as to what you can put in your signature: w3schools links --> allowed w3.org links --> allowed browser links --> allowed html editor links --> allowed personal sites --> allowed tutorial sites competing with w3schools --> NOT allowed sites completely irrelevant to webprogramming and this forum --> NOT allowed   Thanks for understanding, and for taking the time to read this. ~W3Schools Modstaff~
paulmo

upload local file to page

23 posts in this topic

Posted (edited)

W3S, goal is to "upload" local image to display on page via JS. I've grabbed this JQuery script somewhere, can browse and select file, now how to integrate with onclick function (that's working with other text inputs)? Right now nothing's happening, no errors and no images in Network Monitor.

<form action="#" onsubmit="return false">
Upload image
<input type="file" id="upld" value="Choose file"/>
<img id="compImg" src="#" onClick="this.select();"/>
..........etc........

// in button onclick function...v v 
var upldI = document.getElementById("upld").value;  
var compImgVar = document.getElementById("compImg").value;
var img = document.createElement("img");
src = compImgVar;
img.src = src;

//File Upload
        $(function () {
            $(":file").change(function() {
                if(this.files && this.files[0]) {
                var reader = new FileReader();
                reader.onload = imageIsLoaded;
                reader.readAsDataURL(this.files[0]);
                }
            });
        });
        
function imageIsLoaded(e) {
            $('upldI').attr('src', e.target.result);
        };
        container.appendChild(img);
        document.body.appendChild(container);
        };

 

Edited by paulmo
formatting

Share this post


Link to post
Share on other sites

Anything referring to 'upldI' variable as stated here

var upldI = document.getElementById("upld").value;

Will only refer to the value of input element with id 'upld'.

This is referring to text string not variable of element selector for class or id

$('upldI').attr('src', e.target.result);

problems

(1) because  'upldI' variable has a var preceding it, its scope is restricted to scope of onclick event function, it need to be declared outside functions to make it globally available.

(2) As stated at beginning if this variable is global now, it will refer to elements value not element with id 'upldI'.

(3) It targets in wrong element anyway it should target element with id "compImg", this is the img that has 'src' attribute, OR by using corrected variable reference it would target file input then using next() move to next sibling element which is the img

$('#'+upldl.id).next().attr('src', e.target.result);

OR just use actual img id selector ref

$('#compImg').attr('src', e.target.result);

 

Share this post


Link to post
Share on other sites

Posted (edited)

Hi, what's wrong with this now? No image upload, no error, no file in Network console. Thanks.

//inside main btn onclick function

		$(function () {
			$(":file").change(function() {
				if(this.files && this.files[0]) {
				var reader = new FileReader();
				reader.onload = imageIsLoaded;
				reader.readAsDataURL(this.files[0]);
				}
			});
		});
		function imageIsLoaded(e) {
            compImg = document.getElementById("compImg").value;
		    containUp = document.createElement("div");
            containUp.className = "img_descrip_wrap";
            img = document.createElement('img');
            
		    src = compImg;
		    img.src = src;
			$('compImg').attr('src', e.target.result);
            containUp.appendChild(src);
		    document.body.appendChild(containUp);
		};
}; //close onclick function

 

Edited by paulmo
minor edit.

Share this post


Link to post
Share on other sites

If that code really is inside the button click handler, you're not assigning an event to the file input until after the button is clicked. Event listeners should generally be attached in the global scope.

Do you know what each line of that code does?

Share this post


Link to post
Share on other sites
4 minutes ago, Ingolme said:

Hello, If that code really is inside the button click handler (it is) you're not assigning an event to the file input until after the button is clicked. But the input is assigned the onclick() function just like the other inputs... Event listeners should generally be attached in the global scope. Need help seeing this (if it's not the onclick handler).

Do you know what each line of that code does? It seems that FileReader() function is retrieving the 1st value of array [0], in this case 1 file, and it's encoding the image in bytes with readAsDataURL, then the 2nd function applies source attribute and event handler (e), which I thought was the main onclick function, but from your reply it seems something's wrong here. Guidance appreciated, thanks.

 

Share this post


Link to post
Share on other sites

Posted (edited)

You keep repeating tbe same problem, IMG ELEMENTS DO USE A VALUE ATTRIBUTE, ONLY INPUTS USE VALUE AS A ATTRIBUTE, IF YOU KEEP RETRIEVING VALUE FROM A IMG ELEMENT IT WILL NEVER EVER WORK! GOT IT! VALUE ATTRIBUTE FOR IMG NOT WORKY, NOT VALID ATTRIBUTE FOR IMG ELEMENT. VALID ATTRIBUTE YOU REQUIRE TO GET IMG PATH AND/OR FILENAME IS SRC, THIS GOODY, THIS WILL WORKY.

(1) Return imageIsLoaded function to original state, without createElement code etc, but keep $('compImg').attr('src', e.target.result); in there. Also I don't know if this was to refer to variable or typo for id selector, if variable it has rendered the variable useless! Because now surrounded with quotes it refers to element called 'compImg' which does not exist. If typo it should have ‘#‘ at beginning that identifies it as id reference and since we are removing attribute coding it should refer to that

	$('#compImg').attr('src', e.target.result);
	
Edited by dsonesuk
did edit and it removed half my content, and i'm not going to repeat well done ypos

Share this post


Link to post
Share on other sites

(2) Once the description is entered in TEXT input, you have all you require for populating the created img, and created paragraph. The SRC (encoded) of preview image for created img element, and the VALUE of input type text (you might want to consider textarea form element) for paragraph textnode.

(3) Append these created elements to created div container.

(4) Store these src and values in array/s or object array (depending which way you want to go with these), Then pass these arrays through to localstorage.

The creating of elements, retrieving img src, description text value, will be all carried out by event of clicking 'Load' button.

 

Share this post


Link to post
Share on other sites

Also, you're never going to see a request in the network console because you're not sending the file over the network, everything is being done in the browser.  You're reading the local file and updating the page, not sending it to a server.  That's why there's no request to a server.

1 person likes this

Share this post


Link to post
Share on other sites

Posted (edited)

18 hours ago, dsonesuk said:

IMG ELEMENTS DO USE A VALUE ATTRIBUTE

Hi, you meant to shout img elements don't use a value attribute. Revised some things below.

//nested in btn onclick function
		$(function () {
			$(":file").change(function() {
				if(this.files && this.files[0]) {
				var reader = new FileReader();
				reader.onload = imageIsLoaded;
				reader.readAsDataURL(this.files[0]);
				}
			});
		});
        
		function imageIsLoaded(e) {
            compImg = document.getElementById("compImg");
            var count = 1;
            
		    src = compImg;
		    img.src = src;
			$('#compImg').attr('src', e.target.result);
			$('src').append( $(container)); //like this?
            
            return function() { //return to orig. state?
                count++;
            }
		};

}; //close onclick function

 

Quote

Also, you're never going to see a request in the network console because you're not sending the file over the network, everything is being done in the browser.

Thanks for clarification, I see that now.

 

 

Edited by paulmo
responding to multiple replies.

Share this post


Link to post
Share on other sites
38 minutes ago, paulmo said:

Hi, you meant to shout img elements don't use a value attribute. Revised some things below. What should I do now?

YES! that's it

AND No! that is not how that code was originally it was or should have been similar to

 $(function () {
        $(":file").change(function () {
            if (this.files && this.files[0]) {
                var reader = new FileReader();
                reader.onload = imageIsLoaded;
                reader.readAsDataURL(this.files[0]);
            }
        });
    });

    function imageIsLoaded(e) {
        $('#idOfImgElement').attr('src', e.target.result);
    };

BUT! With

$('#idOfImgElement').attr('src', e.target.result);

changed to

$('#compImg').attr('src', e.target.result);

AND it should NOT be nested within any event functions

$(function () {...}); Acts like onload of completely rendered page, if you place this within any event function, because that function only runs after a specific event AFTER the paged has fully loaded, it misses its chance to set the onchange event to convert the img src when the file loading input has changed, which would then read file, ignoring path (for security reasons) , and return as encoded img src, it runs at same time a function to apply this encoded src to img src with id 'compImg'.

So this code is separated from my final code you said had working, that added input text to description array, which was stored in local storage. You now do same process for image, but instead of retrieving image src from text or file input (as mentioned the file input will only show filename not the path to that image for security reasons), you retrieve the src from the preview image encoded src (id="compImg") to add to array, then add img array to localstorage.

Share this post


Link to post
Share on other sites

ok this is outside the btn onlick function now, still trying to figure out how to get file upload image on the page...you said take element etc. out of there but how else to get this on page or even troubleshoot where file is (or is not) going in dev console? Thanks.

}; //close onclick function

//File Upload
		$(function () {
			$(":file").change(function() {
				if(this.files && this.files[0]) {
				var reader = new FileReader();
				reader.onload = imageIsLoaded;
				reader.readAsDataURL(this.files[0]);
				}
			});
		});
        
		function imageIsLoaded(e) {
            var container = document.createElement("div");
		    container.className = "img_descrip_wrap";

            compImg = document.getElementById("compImg");
            var img = document.createElement('img');
		    src = compImg;
		    img.src = src;
			$('#compImg').attr('src', e.target.result);
            container.appendChild(compImg); //tried src, img...
		    document.body.appendChild(container);
          
		};

</script>

 

Share this post


Link to post
Share on other sites

The forum decided to eat my entire post.

src = compImg;
img.src = src;

You're setting the src of an img element to be another img element.  Shouldn't that be this:

img.src = compImg.src;

Is that what you're trying to do?  Create a new img element and set the src of it to the src of an existing img element?

For this part:

container.appendChild(compImg);

compImg is already on the page, is that what you want to append to the new div?  Don't you want to append the element you just created?  Otherwise you're not doing anything with the new element.

Other than that, I would suggest using console.log statements or setting breakpoints to pause the code and look at the values of things.  For example, I would check that e.target.result is something that belongs as an img src.

Share this post


Link to post
Share on other sites

Posted (edited)

You ignore everything I told you do? And placed create image code inside imageisloaded function? You will end duplicating code? The btn onclick will do all that, and it will also act as confirmation before comitting and adding both image and description together to the page, array and finally to localstorage. If you add it to imageisloaded function you risk images and description being processed out of sync to each other and not being tied together on page or arrays.

(1) Get preview image to show and work if it does not already.

(2) Use the onclick of id 'btn' we already had working to retrieve preview img src and description, for creating and adding to page, store in array/s and add to localstorage. The description part was already sorted, you just had to sort the image part to run along with description processing, which will be similar. The only difference is you are reading the src of preview img element.

Edited by dsonesuk

Share this post


Link to post
Share on other sites

Posted (edited)

The image preview is actually working. I made the mistake of working from a closely-named copy file, while leaving the old file up in the browser, so I wasn't seeing changes.

What's happening now is immediately after selecting file, it's rendered on the page. I need it so that it only renders when submit (load) button is clicked (like the other inputs), and compImg will get rendered nicely in the container img_descrip_wrap (it does do this with element created in imageIsLoaded, but only after subsequent file selections, current file selection is always outside the container).

So do I create another document.getElementById('btn').onclick = function() {, after imageIsLoaded(e), calling imageIsLoaded(with or without e), somewhere in the onlick function?

function imageIsLoaded(e) {
      compImg = document.getElementById("compImg"); //don't need value
      $('#compImg').attr('src', e.target.result);
     };
</script>

Also, some general observations...in my onclick function that puts URL image on page, image does not render without .value here (dsonesuk?):

var val = document.getElementById('idImage').value;

whereas this does render, from imageIsLoaded(e) function:

compImg = document.getElementById("compImg");

Also, in onlick function that puts URL image on page img.src = val.src doesn't work, but it does work in imageIsLoaded function

var val = document.getElementById('idImage').value; //need value
        var img = document.createElement('img');
        //img.src = val.src; doesn't work here
        src = val;
img.src = src;
        container.appendChild(img);
        document.body.appendChild(container);

Thanks for continued support.

 

Edited by paulmo
formatting borked

Share this post


Link to post
Share on other sites

You cannot use 'compimg' because its an id ref, you can't use the id within container with 'img_descrip_wrap' class, because as multiple 'img_descrip_wrap' are created along with images, and paragraphs, the id references will also be multiple which IS NOT ALLOWED, trying to access single element or manipulate a element with this id will fail. The file input will not provide a usable image file on its own, you would need server language to upload image to a directory and provide path and file name to that file. This code create encoded copy of image so you not need to download, just use encode url of preview image, that is what the image that shows will provide. If you do not want to have preview image send the encoded url to a hidden type input, and access that value instead.

Share this post


Link to post
Share on other sites

You are using so many, different, renamed id references I don't have any clue what they actually refer to anymore so I can't comment, they could be out of scope, not img, not input, multiple id when they should be unique, all these cause it to fail.

Share this post


Link to post
Share on other sites

Posting the updated script should help (minus getItem localStorage to element/container, that was just an exercise). It's all working great except the file upload needs to go in the container on btn submit (load), not as a full image on file select. Thanks in advance for helping.

<body onload = "lsCheck() ;">

<form action="#" onsubmit="return false">
Upload image
<input type="file" id="upld" value="Choose file"/>
<img id="compImg" src="#" onClick="this.select();"/>
or URL:
<input type="text" name="image" id="idImage" value="" onClick="this.select();"/>
<br><br>
Description:
<input type="text" name="des" id="idDes" value="" onClick="this.select();"/>
<br><br>
<input type="button" id="btn" name="submit" value="Load" />
<br><br>
</form>

<script>
	// checks localStorage
	function lsCheck() {
			lsData = [];
			
		if (localStorage.desSet) {
			//localStorage.removeItem(desSet.splice(0,15));
			lsData = JSON.parse(localStorage.getItem("desSet"));

			//Map replace for loop
			var lsDataMap = lsData.map(function(mapResult) {
				return mapResult;
				});
				console.log(lsDataMap);
			}
            var valDes = lsDataMap; //use lsData[i] in for loop
	}
	document.getElementById('btn').onclick = function() {
	
		//image on page
		var container = document.createElement("div");
		container.className = "img_descrip_wrap";

		var val = document.getElementById('idImage').value; //need value
		var img = document.createElement('img');
		//img.src = val.src; doesn't work here
		src = val;
        img.src = src;
		container.appendChild(img);
		document.body.appendChild(container);
		img.onclick = function () {
			window.open(src);
}
		//descriptions from form submit (below image)
		var valDes = document.getElementById("idDes").value;
		var des = document.createElement("p");

		var tex = document.createTextNode(valDes);
		des.appendChild(tex);

		container.appendChild(des);
		document.body.appendChild(container);
      
		// append current descrip. value into array
		lsData.push(valDes); 
		
		// set entire array to localStorage
		localStorage.setItem("desSet", JSON.stringify(lsData));
      
		//remove: position, # of items.
		//lsData.splice(1,3);
		//remove entire key
		//localStorage.removeItem("desSet");
		
}; //close onclick function

//File Upload
		$(function () {
			$(":file").change(function() {
				if(this.files && this.files[0]) {
				var reader = new FileReader();
				reader.onload = imageIsLoaded;
				reader.readAsDataURL(this.files[0]);
				}
			});
		});
        
		function imageIsLoaded(e) {
            compImg = document.getElementById("compImg"); //don't need .value
			$('#compImg').attr('src', e.target.result);
        
		};

</script>

 

Share this post


Link to post
Share on other sites

This is why it runs when you select a file and the file input field changes:

$(":file").change(function() {

If you want a button to control that then use a click handler for the button and get the file input by ID to get the list of files.

Share this post


Link to post
Share on other sites

You need the upload for images on a users computer, because it creates encoded image source of the actual image, without the need for downloading and storing on website server.

You need the text input for the url of website image url, where you copy the image location, and paste.

Now you need to identify which is required to be displayed and stored, by checking both the upload preview image and URL input, then whichever is not empty, that is the one to process. After this and the description have been processed appended to array, stored in localstorage you need to reset file upload input AND preview image src to "", along with URL input, ready for the next image and description.

You also might want set up if focus of either input, reset the alternative automatically, also make sure one of both image inputs and description input are not empty, before processing, and clear both inputs, image if reload of page takes place.

Share this post


Link to post
Share on other sites

Thanks JSG for the lead that change(function() controls loading the file when file is clicked. How to integrate that with btn onclick function (handler) eludes me at this point but I'm going to try to get some help with that. Re: "get the file input by ID to get the list of files" -- the file input ID compImg to get a list of what files?

dsonesuk, "reset file upload input and image src to "" sounds interesting. W3S example shows appending .reset() to form id. Whi ch function would I put that in?

I understand checking inputs and description so not empty. What purpose would focus() have here? Right now the images do get cleared on page reload.

Share this post


Link to post
Share on other sites

You don't need to integrate loading change with btn click, it job is to on change of file selection, create encoded image, and you then retrieve that data to show and store. So as already suggested leave as is.

The button click will retrieve data from either preview img element, (or instead a hidden input if you choose) storing encoded image data IF upload option is used, ELSE retrieve the URL input data. Both would have to be checked to identify which option is used, as in none empty encoded image data src or none empty URL input value AND assign whichever used to a variable for processing.

After all processing is taken place within button click event function you need to clear all values and/or src of preview image encoded data, but note that the file upload input retains the filename value even after reload as it is different from a ordinary text input, so using .value=""; won't be enough, and if reset() used it will need to be initiated within click event function after processing has taken place.

The focus() can be used if the user changes mind or made mistake in chioce of image retrieving option, as in when the user selects the alternative option it will clear the previously filled input AND possibly src of encoded image data.

Share this post


Link to post
Share on other sites

file input ID compImg to get a list of what files?

The file input ID upld, to get the list of selected files.  That's what you do here:

if(this.files && this.files[0])

But if that is going to run on a button click, then this will not refer to the file input, so you need to get it by the ID and then check the file list.

Share this post


Link to post
Share on other sites

There will always be 1 file listed, the current file you selected, but since you are not uploading the selected image, its pointless referring to this, as you will be using the encoded data of the selected image that is returned by this code and used in the preview image with id 'compimg' attribute src, which is what you should refer to.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now