Solved

need help displaying better images with plupload

Posted on 2014-12-30
9
569 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:NeilT
  • 6
  • 3
9 Comments
 
LVL 3

Author Comment

by:NeilT
Comment Utility
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
Comment Utility
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:NeilT
Comment Utility
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
 
LVL 82

Expert Comment

by:leakim971
Comment Utility
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 3

Author Comment

by:NeilT
Comment Utility
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
Comment Utility
it look good for me
0
 
LVL 3

Author Comment

by:NeilT
Comment Utility
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:
NeilT earned 0 total points
Comment Utility
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:NeilT
Comment Utility
solved issues and posted complete, commented solution to assist others
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

In this article you'll learn how to use Ajax calls within your CodeIgniter application. To explain this, I'll illustrate how to implement a simple contact form to allow visitors to send you an email through your web site.
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn the basics of jQuery including how to code hide show and toggles. 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…

743 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

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now