A Brief Review of JavaScript: How we used JavaScript to write a media library

Guest Blogger

We've talked previously about what JavaScript is, we've talked about Why we use it on the front end, but let's go into the specifics on How we use JavaScript to extend the functionality of websites.

How we use JavaScript.

Most modern websites are divided into roughly three sections. The "Front End" of a website, which is what users will see when they are browsing your website, maybe reading a blog post like you are now. The "Back End" or "CMS" of a website is an administrative section of the website that is designed to make updating the website easier for people without the technical skills to do the changes manually. And finally, you have the server side part of your website, the files that actually live on a computer somewhere. One of the largest ways we use JavaScript is to facilitate juggling tasks the website wants/needs to perform between that server computer and whatever device is using the front end or back end of the website. The previous blog post talked a lot about AJAX calls and using JavaScript to initiate CSS changes or directly manipulate the underlying DOM of your website.

These are powerful, and can add a lot of user interactivity to a website, but JavaScript isn't limited to that. We can also create full pseudo-applications where all of the technologies interact to deliver something that wouldn't be possible otherwise.

For a better example of this, let's focus on one feature of our CMS, Arrow, the What You See Is What You Get (WYSIWYG) editor. We integrate a JavaScript-based editor known as CKEditor. Because JavaScript has an understanding of the DOM by default, JavaScript is uniquely positioned as a language to create HTML style documents. CKEditor works by keeping an internal copy of the DOM structure and manipulating it based on user input. It utilizes an iFrame (an HTML object that allows one HTML document to contain another without the two interfering with each other) so that it can inject a large number of custom CSS rules to create a Microsoft Word-esque user interface. One of the largest benefits of this approach is that we can ask the editor to switch between rendered (how it will appear on the website) and code views so that we can do more technical or complicated work than we would be able to do if it didn't.

One of the huge benefits of this editor being JavaScript based, outside of it being a piece of software that doesn't have to be installed or configured by the user, is that it is extendable. CKEditor is its own Open Source project run by its own team, but our CMS has specific needs, which means that we needed to customize the editor. One of the larger customizations in recent memory is our media library. The media library solved a problem we had: the file uploader we were using for the editor was no longer being actively maintained, looked dated, and was becoming something of a security concern. Our media library needed two functionalities, a file browser and a file uploader, both of which needed to function completely without page loads, otherwise, users would lose whatever work they had been doing before the opened the media library.

To facilitate this, we needed a large number of AJAX communications between our server, which would deliver lists of files (filtered down to just viable media files) and parse file uploads. Displaying the files is the easy part. In our case, we actually let the server handle the building of the HTML that displays the files, and the only thing the JavaScript is responsible for is putting the generated HTML in the right location. The slightly more complicated part was the upload. The following is a slightly modified version of our uploader script, and you'll notice that while we don't directly support it, the JavaScript is already prepared to allow multiple files to be uploaded at once.

	mediaBrowser.upload = function(event){
		$('#menu').find('.fa-cog').addClass('fa-spin');
		files = event.target.files; 
		//This contains the filenames the user chose to upload
		var data = new FormData(); 
		//This generates our form object.
		var error = 0;
		
		for(var i = 0; i < files.length; i++){ 
		/* We start at the first file, and loop all the way 
                through the array. Even though we don't allow 
                multiple uploads through this interface yet, 
		the JavaScript knows how to process them. */
			var file = files[i];
			if(file.size > 2097152){
				error = 1;
				$('#menu').find('.fa-cog').removeClass('fa-spin');
			}else{
				data.append('file', file, file.name);
			}
		}
		data.append('dir', $('#output').attr('data-dir')); 
		/* Here we tell the uploader where we're uploading the file. 
		The server will validate this on the other side to ensure 
                the user has permission to upload to this directory. */
		if(error != 1){
			/* Finally, if we can send our data (if it wasn't too 
                        large to send), we do */
			$.ajax({
				url: '/tool/media/',
				data: data,
				dataType: 'json',
				processData: false,
				type: 'POST',
				contentType: false,
			}).done(function(variable){
				console.log(variable);
				mediaBrowser.get();
			}).fail(function(err){
				$('#media_filter').val(file.name);
			}).always(function(){
				$('#menu').find('.fa-cog').removeClass('fa-spin');
				mediaBrowser.get();
			});
		}else{
			$('#menu #file').val('');
			$('#menu #file').css('border: 1px solid red;');
		}
	}

Using the built-in JavaScript FormData object, we can create an upload form submission for the user, handle it server side like we always do, all without needing the user to load a whole new document on success. This also allows us to search for the file the user just uploaded, making it easier to find what you just uploaded in multi-user settings, like our blog where files stack up over time.

An image of the Arrow Media LibraryThe final result

In addition to this AJAX uploader, we have a lot of user convenience features like the ability to switch between list and tile mode, being able to see image previews just like in a desktop file explorer, all of this is switched out on the fly by sending requests back to the server with the new settings, and having it reply with the new HTML.

If you're into JavaScript, hopefully, this gave you an idea of how you can start to apply some of the basic concepts to more complicated and useful tasks, but one of the great things about such an accessible language is that the world is full of alternate solutions to problems like these. Think you have another one? Feel free to reach out and let us know. Need us to put our JavaScript knowledge to work on a problem you or your users are having? We'll be happy to hear from you.