How I randomly re-order my portfolio modules with Javascript

This is a quick demonstration of how I was able to write a series of divs in random order to my homepage using javascript. To see the code I’m about to show you in action, you can go to this site’s homepage, notice the grid of linked images, and refresh. The grid will refresh in an entirely different, random order.

Prior to this change, I was using a php include to import a list of individually written divs. Each div, which I’ll call a module, contained externally styled html that specified an image, a thumbnail, an inline styled background color, and a class for the linked image. Here’s an example of one of those modules:

<div class="pic" style="background-color:#45963A">
<a class="fancybox" rel="gallery" href="./images/habitat.png">
<div class="info">Logo for Habitat Architects</div>
<img src="./images/thumbs/habitat.png" title="Vector Logo, 2009"/>
</a>
</div>

I have five categorized files populated with modules similar to these, and a navigation menu that will take you to a specific category. But I didn’t want a new visitor to see only one category, and possibly conclude in a half second glance that the one category comprised all the work I want to show. So the index page initially included all five categories together, like this:

<div id="grid">
<?php include("./portfolio/illustration.php") ?>
<?php include("./portfolio/identity.php") ?>
<?php include("./portfolio/advertising.php") ?>
<?php include("./portfolio/product.php") ?>
<?php include("./portfolio/publishing.php") ?>
</div>

The result of this looked ok, but I didn’t like how the various styles seemed clumped together. For example, the logo/identity thumbnails almost all have a white background, so there was this group of white background images grouped all together that seemed to break the flow of the page. The other categories had their own similar issues. It looked like this:

I wanted to mix these thumbnails up so that the overall texture of the page was more evenly distributed. And I didn’t want to burden myself with manually mixing up the modules using static html. My initial idea was to create a mysql database, with a row for each portfolio piece, and a column to represent each variable. The variables would be the two image filepaths, a hexedecimal color code, a string of descriptor text, and a size class for the final image. I believe this would work, but I didn’t want to spend the amount of time it would take to enter all that data in an mysql table.

Instead, I wrote a javascript function to create variables and inject them in to a block of html that could be reused for each module. It looks like this:

//Constructor for Portfolio Modules
function portMod(id, color, size, thumb, image, info, category) {
this.id = id;
this.color = color;
this.size = size;
this.thumb = thumb;
this.image = image;
this.info = info;
this.category = category;
}

This object constructor function called portMod() creates objects with properties that represent the variable data that will differentiate each module. In order for this to work, I need an array with the actual data to loop through to build the html I need. To accomplish that, I ended up doing some manual data entry after all, but at least it wasn’t into a database table, and can be easily updated in a single text file. I won’t paste the entire array here. But here is a sampling of a few lines that use portMod() to create the array I need, called ‘portfolio':

//Creating the Portfolio Array. A container for the Modules.
var portfolio = [];

//Filling the array with the actual data to fill the page. Image paths, hex codes, etc.

portfolio[0] = new portMod(0, 'd41c17', 'fancybox', 'free_th\.png', 'free\.png', '\"Free\" India Ink & Flashe, 2009', 'illustration');

portfolio[1] = new portMod(1, '632c3f', 'fancybox', 'marchiali_th\.jpg', 'marchiali\.jpg', 'Marchiali: The Man in the Iron Mask', 'illustration');

portfolio[2] = new portMod(2, '0F97A4', 'fancybox', 'togh\.gif', 'TOGHOWTR\.jpg', 'Good Hands\: Acrylic Paint 2010', 'illustration');

Etcetera.

At this point, I have an array of objects called ‘portfolio.’ Each object has 7 properties that I’ve assigned. Five of the properties will serve as variables for injecting into my html, and I’ve also added an ‘id’ property, and a ‘category’ property. I think those two will help me sort and do other cool things with this data in the future, but right now, I really only need ‘color,’ ‘size,’ ‘thumb,’ ‘image,’ and ‘info’ to do what I want to do next.

The values for these properties will be inserted into my original html module. The next piece of code I’m going to show you does two things. First, it calls a function called shuffle() which I’ll talk about in a moment, to re-order all of the module objects in the ‘portfolio’ array. So the elements of that array are already shuffled before any html is generated. Second, it uses a for loop to loop through the ‘portfolio’ array, inserting all the variables in to the block of html with escaped quotes and slashes so it can be processed as a series of strings, concatenating them with the object properties. Each module is written to the page using the document.write() method. Here is the code:

function showPort() {
shuffle(portfolio);
for (x in portfolio) {

document.write("<div class=\"pic\" style=\"background-color:#" + portfolio[x].color + "\"><a class=\"" + portfolio[x].size + "\" rel=\"gallery\" href=\".\/images\/" + portfolio[x].image + "\"><div class=\"info\">" + portfolio[x].info + "<\/div><img src=\".\/images\/thumbs\/" + portfolio[x].thumb + "\" title=\"" + portfolio[x].info + "\"\/><\/a><\/div>");
}

Without the shuffle() function, all of this would just re-write what I had in the beginning, a static sequence of modules in whatever order they were found in the ‘portfolio’ array. The key to writing them randomly is to mix up the indexes of that array using a randomization algorithm. There is a recurrent need for randomization in almost all applications of computer science, and so there are plenty of existing algorithms to choose from. I discovered the Fisher-Yates method on this Stackoverflow thread. I used the exact javascript version of this algorithm posted by CoolAJ86, and it works beautifully here by calling the shuffle() function using ‘portfolio’ as the array parameter. Explanation as to how it works can be found elsewhere, so I won’t get in to it. I place the function at the beginning of my file so it exists when I need it. Here is my javascript file with everything in the proper order.

Finally, I call the showPort() function from within my html file, replacing the five php includes I mentioned before, like this:

<div id="grid">
<script type="text/javascript">
showPort();
</script>
</div>

I want to end this by commenting on why I would even want to randomize my portfolio in the first place. After I did all this work, I came across this essay written by Kyle Meyer, where he explains some of the problems he percieved in many art & design portfolios. He points out the obscurity that can be created using thumbnails, and the common problem of cryptic navigation techniques which can be difficult to bookmark. I’ll admit that some of this is applicable to my site, possibly compounded by adding randomization to a grid of thumbnails. What’s my excuse?

Everytime I create a thumbnail for this site, I recompose the design to fit within a square. There are no random croppings, and the composition is generally large enough to see what is in the image. What if someone wants to revisit an image later? I just shuffled the thumbnails around, so it isn’t in the same place it was last time they visited the site. Well, I still have navigation that takes visitors to non-random categorized pages, so I think there is still a fair opportunity to come back to something specific. From a site maintenance standpoint, I’ll simplify that even further in the future using the ‘category’ and ‘id’ properties I created in my ‘portfolio’ array.

I hope that by adding a little randomness to my homepage I’ve done something to encourage curiosity and a sense of exploration. Something less accomodating to the caracaturistic ‘user’ that is confused by every navigational modifier in the interface he is engaged with. Not only that, but it is a document that will continue to grow, and given the diminishing likelihood of a returning visitor to scroll anywhere to find new material, he is presented with new material that by randomization is given equal prominence with the old.