Solved

need help displaying better images with plupload

Posted on 2014-12-30
9
720 Views
Last Modified: 2015-01-05
Hi

I'm currently writing a shop for a friend and the add item page needs to be able to allow x number of image uploads to go with the item for sale.

I'm using plupload ( http://www.plupload.com ) which seems quite good and I' believe also used in WordPress etc.

I have the following code that does a basic job how I want it but it needs a few polishing bits, perhaps some of you javascript / jQuery gurus could assist please ( as this has taken me a while to get this far grabbing bits from lots of examples :( )

Heres the code so far based on a basic install of plupload
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js" charset="UTF-8"></script> 
    <script type="text/javascript" src="../../js/plupload/plupload.full.min.js"></script>
    <script type="text/javascript" src="../../js/plupload/jquery.ui.plupload/jquery.ui.plupload.min.js" charset="UTF-8"></script> 
    
    <title>Untitled Document</title>
</head>

<body>

<div id="filelist">Your browser doesn't have Flash, Silverlight or HTML5 support.</div>

<br />
 
<div id="container">
    <a id="pickfiles" href="javascript:;">[Select files]</a> 
</div>
 
<br />

<pre id="console"></pre>
 
<input type="text" id="itemImage1" name="itemImage1" size="50" value=""/><br>
      
<script type="text/javascript">

	(function( $, plupload ) {
			
	 
		var uploader = new plupload.Uploader({
			
			runtimes : 'html5,flash,silverlight,html4',		 
			browse_button : 'pickfiles',
			container: document.getElementById('container'), 		 
			url : "upload.php",		 
			filters : {
				max_file_size : '30mb',
				mime_types: [
					{title : "Image files", extensions : "jpg,jpeg,gif,png"}
				]
			},
			preserve_headers: true,	
			max_file_count: 1,
			unique_names:true,
			autostart: true,
			max_file_size : '50mb',		
			chunk_size: '1mb',
			resize : {
				width : 800, 
				height : 800, 
				quality : 90,
				crop: false // crop to exact dimensions
			},
			flash_swf_url : '../../js/plupload/Moxie.swf',
			silverlight_xap_url : '../../js/plupload/Moxie.xap',
		 
	 
			init: {
				PostInit: function() {
					document.getElementById('filelist').innerHTML = ''; 
				},
		 
				FilesAdded: function(up, files) {
					plupload.each(files, function(file) {
						showImagePreview(file);
						document.getElementById('filelist').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ') <b></b></div>';
						uploader.start();
					});
				},
		 
				UploadProgress: function(up, file) {
					document.getElementById('itemImage1').value = file.target_name;
					document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";
				},
		 
				Error: function(up, err) {
					document.getElementById('console').innerHTML += "\nError #" + err.code + ": " + err.message;
				}
			}
			
		});
	
		uploader.init();
		
		function showImagePreview( file ) {
			
			var item = $( "<span></span>" ).prependTo( "#console" );
			var image = $( new Image() ).appendTo( item );
			var preloader = new mOxie.Image();
			
			preloader.onload = function() {
				preloader.downsize( 200, 200 );
				image.prop( "src", preloader.getAsDataURL() );
			};
			
			preloader.load( file.getSource() );
	
		}
			
	})( jQuery, plupload );
  
</script>

</body>
</html>

Open in new window


At present this is what it does:

# allows for the selection of an image
# uploads it after selection (renaming uniquely)
# creates a thumbnail (base64, but I'm sure there are better ways, the demo seems to do one much nicer but I cant see how?)
# adds the new unique name to a input box (as I will need to have these as an array to send with the item details to know # when the page is viewed what images to then show

This is what I need it to do

# append each newly uploaded image unique name into the itemImage1 text box
# have a delete button with each image so the user can remove an item (this will also delete from the itemImage1 text box
# display a better thumbnail, does jQuery have a better way of doing this?
# limit the images in total to 5, I guess this is some sort of jQuery count on the elements in a container? but well out of my league with JavaScript

Please do not just push me in the direction of examples. I learn quickly but only when I can see how my implementation works so would appreciate ideas based on my code, or a better working entire plupload solution here please.

user selects file
select-1.png
upload complete and thumbnail displayed with unique name (created by plupload in text box)
select-2.png
need to limit to 5 total images allowing deletion of any/all images hiding the {select} option when max is reached but showing again when images are deleted.
select-3.png
0
Comment
Question by:Neil Thompson
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
9 Comments
 
LVL 3

Author Comment

by:Neil Thompson
ID: 40523688
ok, I've worked out how to remove the [Select files] when the image count = 5 :)

FilesAdded: function(up, files) {
   plupload.each(files, function(file) {
      showImagePreview(file);
      document.getElementById('filelist').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ') <b></b></div>';
     
---->      var numberOfUploadedImages = $("#filelist div").length;
---->      if (numberOfUploadedImages==5) { $("#pickfiles").hide(); }


      uploader.start();
    });
				},

Open in new window

0
 
LVL 82

Expert Comment

by:leakim971
ID: 40523819
Please do not just push me in the direction of examples. I learn quickly but only when I can see how my implementation works so would appreciate ideas based on my code, or a better working entire plupload solution here please.

So why not splitting your project in at least four questions?
0
 
LVL 3

Author Comment

by:Neil Thompson
ID: 40523831
sorry, what do you mean please?
I'm trying to ask for assistance to achieve my request using "my" code, not example codes that are different from mine (that's where I'm struggling to see how to then implement them in to mine), hope that makes more sense
0
Quiz: What Do These Organizations Have In Common?

Hint: Their teams ended up taking quizzes, too.

 
LVL 82

Expert Comment

by:leakim971
ID: 40523833
This Is What I Need It To Do

1) append each newly uploaded image unique name into the itemImage1 text box
2) have a delete button with each image so the user can remove an item (this will also delete from the itemImage1 text box
3) display a better thumbnail, does jQuery have a better way of doing this?
4) limit the images in total to 5, I guess this is some sort of jQuery count on the elements in a container? but well out of my league with JavaScript
0
 
LVL 3

Author Comment

by:Neil Thompson
ID: 40523834
I've also crudely worked out a way to add the removal button I think, could possibly be made slicker?

----->				// remove image
----->				var wrapper = $("#console"); //Fields wrapper
----->				$(wrapper).on("click",".remove_field", function(e){ //user click on remove text
----->					e.preventDefault();
----->					$(this).parent('span').remove();
----->				})
	
		uploader.init();
		
		function showImagePreview( file ) {
			
			var item = $("<span></span>").prependTo("#console");
----->		var removeLink = $("<a href='#' class='remove_field'>Remove</a><br/>").prependTo(item);
			var image = $(new Image()).appendTo(item);
			var preloader = new mOxie.Image();
			
			preloader.onload = function() {
				preloader.downsize( 200, 200 );
				image.prop( "src", preloader.getAsDataURL() );
			};
			
			preloader.load( file.getSource() );
	
		}

Open in new window

0
 
LVL 82

Expert Comment

by:leakim971
ID: 40523848
it look good for me
0
 
LVL 3

Author Comment

by:Neil Thompson
ID: 40525130
I intend to ask support to close this question as I have altered the code substantially and fixed many of the issues requested. Additionally then layout of the request as noted isn't very clear.

I will tidy up my working code, and post it below to assist others then ask a new question to solve the issues if no-one that has commented has any objections
0
 
LVL 3

Accepted Solution

by:
Neil Thompson earned 0 total points
ID: 40525174
Here is my working code based on my original question, there are bits of it that do not yet fully work as required.

This may help someone down the line that wants to use plupload to

1) select x images (1 at a time, although this can be altered)
2) upload them once selected (again can be altered)
3) resize them on the fly before uploading (can be altered)
4) allow the option to remove an image from the DOM (not the file system)
5) hide the upload button from view when the max limit of files is reached, adding again if images are removed

What this code doesn't yet do nicely:

1) provide a way to remove the associated unique name from the hidden field array of uploaded images
2) utilise the image upload thumb as effectively as possible (this works out the upload path and scales the image rather than doing something on the fly)

adding images with select button, remove link and list of assiciated unique file names
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js" charset="UTF-8"></script> 
    <script type="text/javascript" src="../../js/plupload/plupload.full.min.js"></script>
    <script type="text/javascript" src="../../js/plupload/jquery.ui.plupload/jquery.ui.plupload.min.js" charset="UTF-8"></script> 
    
    <title>Untitled Document</title>
</head>

<body>

<div id="imageGalleryState">Your browser doesn't have Flash, Silverlight or HTML5 support.</div>

<br />
 
<div id="selectFilesContainer">
    <a id="pickfiles" href="javascript:;">[Select files]</a> 
</div>
 
<br />

<div id="imageGalleryContainer"></div>
 
<textarea id="associatedImages" name="associatedImages" cols="60" rows="10"></textarea><br>
      
<script type="text/javascript">	

	(function( $, plupload ) {			
	 
	 	// create a new instance of the uploader
		var uploader = new plupload.Uploader({
						
			runtimes : 'html5,flash,silverlight,html4',						// runtime setup	 
			browse_button : 'pickfiles', 									// select files button
			container: document.getElementById('selectFilesContainer'),		// selected files container
			url : "upload.php",												// URL of uploader
			filters : {
				max_file_size : '30mb',										// max single file size (plupload compresses client size so upload will be small :)
				mime_types: [
					{title : "Image files", extensions : "jpg,jpeg,gif,png"}// upload types to allow
				]
			},
			preserve_headers: true,											// retain EXIF info (good for iphone images etc as it then knows the right way up
			max_file_count: 1,												// only allow 1 file at a time to be uploaded
			multi_selection:false,											// do not allow multiple selections
			unique_names:true,												// rename on the fly
			autostart: true,												// auto upload when selected
			chunk_size: '1mb',												// split into 1mb chunks (only really needed for huge files)
			resize : {
				width : 800,												// resize width
				height : 800,												// resize height
				quality : 90,												// resize quality
				crop: false													// do not crop
			},
			flash_swf_url : '../../js/plupload/Moxie.swf',					// URL for flash uploader
			silverlight_xap_url : '../../js/plupload/Moxie.xap',			// URL for silverlight uploader
		 
		 
	 		// Fires when the current RunTime has been initialized.
			init: {
				
				// Fires after the init event incase you need to perform actions there.
				PostInit: function() {
					document.getElementById('imageGalleryState').innerHTML = ''; 
					document.getElementById('associatedImages').innerHTML = ''; 
				},
		 		
				// Fires after files were filtered and added to the queue.
				FilesAdded: function(up, files) {				
					// loop through files, if there are 5 then hide the add button 
					plupload.each(files, function(file) {	
						uploader.start();
						var numberOfUploadedImages = $("#imageGalleryContainer div").length;
						if (numberOfUploadedImages < 5) { $("#pickfiles").show(); }
						if (numberOfUploadedImages == 5) { $("#pickfiles").hide(); }				
					});
					// update the file container so we know what images are assigned to this item
					// this is sent in the form post on submission
					updateAssociatedImages(files);
				},
				
				// Fires when a file is successfully uploaded.
				FileUploaded: function(up, file, info) {
					// shows the thumb of the uploaded image
					showImagePreview(file);
				},
		 
		 		// Fires while a file is being uploaded. Use this event to update the current file upload progress.
				UploadProgress: function(up, file) {
					//document.getElementById('associatedImages').value = file.target_name;
				},
		 
		 		// Fires when a error occurs.
				Error: function(up, err) {
					document.getElementById('imageGalleryContainer').innerHTML += "\nError #" + err.code + ": " + err.message;
				}
			}
			
		});
	
	
		// Initializes the Uploader instance and adds internal event listeners.
		uploader.init();
		
		
		// provide the ability to remove images
		// This DOES NOT remove the image from the server, only from the DOM (and ideally in my case) the associatedImages hidden field
		var igc = $("#imageGalleryContainer");
		$(igc).on("click",".remove_field", function(e){ 
		
			// remove the selected image
			e.preventDefault();
			$(this).parent('div').remove();
			
			 /* ------ TO-DO ------ */
			// update the associated images container
			var getRemovedTargetName = $(this).parent('div');
			//alert(getRemovedTargetName.get(0).outerHTML);
			
			// if the removal brings the total below 5 also show the add button again		
			var numberOfUploadedImages = $("#imageGalleryContainer div").length;
			if (numberOfUploadedImages <5) { $("#pickfiles").show(); }		
							
		})
		
		
		// creates a thumbnail based on the uploaded image unique name and the upload path
		// in this case based on folders for year / month / day / [unique file nalme]
		function showImagePreview( file ) {	
				
			// create a div to hold the image
			var item = $("<div></div>").prependTo("#imageGalleryContainer");
			
			// add a remove link
			var removeLink = $("<a href='#' id='"+file.target_name+"' class='remove_field'>Remove</a><br/>").prependTo(item);
			
			// work out where the image was uploaded to
			var uploadURLPrefix = "../../uploads/user/plupload/";				
			var d = new Date();
			var mkFolderYear  = d.getFullYear();
			var mkFolderMonth = d.getMonth()+1; // 0-11
			var mkFolderDay   = d.getDate();
			var uploadFullPathForThumb = uploadURLPrefix + mkFolderYear + '/' +  mkFolderMonth + '/' + mkFolderDay + '/' + file.target_name;
			
			// add the image thumb
			var imageThumb = $("<img src='"+uploadFullPathForThumb+"' class='addImageThumb' height='120'/>").appendTo(item);	
			
		}
		
		
		// I want to be able to create a hidden form field I can post with my item that
		// will store in the database all the related images for this item
		// this is the best way I could think to do it but this will be improved
		function updateAssociatedImages (files) {
			
			// get the value of the associated images container
			var ai = document.getElementById('associatedImages').value;
			
			// add the latest uploaded image to the associated images
			plupload.each(files, function(file) {
				ai += ' ' + file.target_name;
				ai = ai.replace(/\s{2,}/g, ' ');
				document.getElementById('associatedImages').value = ai;				
			});
			
		}
		
			
	})( jQuery, plupload );
  		

</script>

</body>
</html>

Open in new window


Once I have those options fixed I'll also post that code below to assist. Hope it helps someone :)
Neil
0
 
LVL 3

Author Closing Comment

by:Neil Thompson
ID: 40531158
solved issues and posted complete, commented solution to assist others
0

Featured Post

Get Actionable Data from Your Monitoring Solution

Your communication platform is only as good as the relevance of the information you send. Ensure your alerts get to the right people every time with actionable responses. Create escalation rules that ensure everyone follows the process and nothing is left to chance.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Requirements JQuery 1.6+ HTML CSS Introduction This article was inspired by an EE question (http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_28372511.html) on how to make a page show some balloons animate up a page…
JavaScript can be used in a browser to change parts of a webpage dynamically. It begins with the following pattern: If condition W is true, do thing X to target Y after event Z. Below are some tips and tricks to help you get started with JavaScript …
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)

718 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question