How to display random selections of content from a list




What is it all about?

You may be interested in a list, from which a random image or link or something else is shown, when triggered by some event. It might be something like recommend movies like I have done on the site WeirdSpace.info, showing a random image and link when the page is opened or updated. It is one of the small effects that can liven up a page with a static content a little.

Such a solution consists of two parts, a list and a selector for random selection. For short lists you will often do it in one JavaScript. If the list is very long, having it in a separate file, e.g. an XML database, is an advantage. Both solutions will be shown.





List and selector together

The first thing to do, when working with list and selector in the same file, is the list itself. Here we call the items on the list for images[], and they are numbered sequentially, starting at zero, i.e. the first item is called images[0], the second item images[1], etc. For this demo, each item is an HTML code for a link with an image. Before the list, you declare that the images[] is a list by using Array(). The reason you start with images[0] instead of images[1] is due to the way the randomization command works, which will be shown below.

As code, the list looks like this:

images = new Array();

images[0] = "<A HREF = 'https://weirdspace.info/…/Tangled_2010.htm'><IMG SCR='https://weirdspace.info/…/Tangled_2010.jpg' STYLE='float:none; margin-left:20px'></A>";

images[1] = "<A HREF = 'https://weirdspace.info/…/TheDeep_1977.htm'><IMG SCR='https://weirdspace.info/…/TheDeep_1977.jpg' STYLE='float:none; margin-left:25px'></A>";



images[15] = "<A HREF = 'https://weirdspace.info/…/NightAtTheMuseumIII_2014.htm'><IMG SCR='https://weirdspace.info/…/NightAtTheMuseumIII_2014.jpg' STYLE='float:none; margin-left:25px'></A>";

images[16] = "<A HREF = 'https://weirdspace.info/…/TheyDriveByNight_1940.htm'><IMG SCR='https://weirdspace.info/…/TheyDriveByNight_1940.jpg' STYLE='float:none; margin-left:25px'></A>";


The paths to links and images are truncated to make the example more readable. In the actual code, you have the full path written, obviously.

JavaScript can only do randomization of numbers by using Math.random(), which select a random number between 0 and 1, excluding 0 and including 1. In math this interval is written as [0 ; 1[. Here, however, we need a number in the interval 0 to 16, and this is done by multiplying the number, generated by Math.random(), with the number of items on the list. Because we have defined images[] as an array, we can find the number of items on the list by using .length, i.e. images.length. You can of course also write the actual number, but then you have to remember to adjust the code here, every time you add or remove items. Updating the code is less troublesome, using images.length, so that solution is definitely recommended.

When it comes to the number of items, you have to be a bit careful. You have 17 items, so by multiplying Math.random() with images.length, i.e. Math.random() * images.length, you get numbers going from 0 to just below 17. All the number on the images are integers, so getting a decimal number is no good. Integers you get by rounding off. In JavaScript you can round off by using floor(), which will always round down, ceil() (an abbreviation for ceiling), which will always round up, and round(), which will round up or down, depending on the decimal. Here we use floor(), i.e. Math.floor(), so it always rounds down. For 17 items, the routine will always give you an integer in the interval 0 to 16.

The calculated value we call RandomNumber in this example, and the code looks like this:

RandomNumber = Math.floor(Math.random() * images.length);

Now we need to get the random value, RandomNumber, converted to the HTML code that goes with the list. Then it looks like this:

document.write(images[RandomNumber]);


The the entire code looks like this:

images = new Array();

images[0] = "<A HREF = 'https://weirdspace.info/…/Tangled_2010.htm'><IMG SCR='https://weirdspace.info/…/Tangled_2010.jpg' STYLE='float:none; margin-left:20px'></A>";

images[1] = "<A HREF = 'https://weirdspace.info/…/TheDeep_1977.htm'><IMG SCR='https://weirdspace.info/…/TheDeep_1977.jpg' STYLE='float:none; margin-left:25px'></A>";



images[15] = "<A HREF = 'https://weirdspace.info/…/NightAtTheMuseumIII_2014.htm'><IMG SCR='https://weirdspace.info/…/NightAtTheMuseumIII_2014.jpg' STYLE='float:none; margin-left:25px'></A>";

images[16] = "<A HREF = 'https://weirdspace.info/…/TheyDriveByNight_1940.htm'><IMG SCR='https://weirdspace.info/…/TheyDriveByNight_1940.jpg' STYLE='float:none; margin-left:25px'></A>";

RandomNumber = Math.floor(Math.random() * images.length);

document.write(images[RandomNumber]);

The code at it is done here, has to be saved in a separate file, which we call MovieRecommendations.js and place in the directory JavaScripts. We can now call the file from wherever we want the image and link show on the page. The code to be written, where you want image and link placed, is:

<SCRIPT TYPE="text/javascript" SRC="JavaScripts/MovieRecommendations.js"></SCRIPT>


On the screen it looks like this (try updating the page by pressing F5):







List and selector as separate files

If you need a separate file, it has to have a fixed structure. For this example, we use an XML database, but it might as well have been an Access database or a comma separated file.

We start with the creation of an XML database. The file we name Jokes.xml, and the structure looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<Jokes>

<Joke>
<text_string><![CDATA[As a little boy climbed onto Santa's lap, Santa asked the usual, "And what would you like for Christmas?"<BR>
The child stared at him open mouthed and horrified for a minute, then gasped, "Didn't you get my E-mail?"]]></text_string>
</Joke>

<Joke>
<text_string><![CDATA[Why did the horse cross the road?<BR>
- Because the chicken needed a day off!]]></text_string>
</Joke>



<Joke>
<text_string><![CDATA[- How can you tell the difference between an attorney lying dead in the road and a coyote lying dead in the road?<BR>
With the coyote, you usually see skid marks.]]></text_string>
</Joke>

<Joke>
<text_string><![CDATA[- What do you call two elephants on a bicycle?<BR>
Optimistic!]]></text_string>
</Joke>

</Jokes>


The first thing to do, in order to use external lists, is getting access to them. For this we use the script loadXMLDoc. How this is constructed, you can see here (Remember to upload the script in the page's HEAD tag, as described). Here we place the file Jokes.xml in the same directory as the HTML file, and then the first line in the script looks like this:

<SCRIPT TYPE="text/javascript">
xmlDoc=loadXMLDoc("Jokes.xml");

</SCRIPT>


We now have access to the file, so the next thing to do, is grabbing the individual jokes. This is done with a variable, Joke_lmnt, where we fetch the values using getElementsByTagName(). Here it is the tag text_string containing the individual jokes.

We are also going to need the number of jokes in the file, so we know the interval in which to pick a random number. You can count then, obviously, but then you have to edit the JavaScriptet every time you ad or remove something from the list. Instead we use the command .length for the number of elements in the variable Joke_lmnt.

Then the code looks like this:

<SCRIPT TYPE="text/javascript">
xmlDoc=loadXMLDoc("Jokes.xml");

var Joke_lmnt = xmlDoc.getElementsByTagName("text_string");
NumberOfElements = Joke_lmnt.length;

</SCRIPT>


Now we have to pick a random number. It has to be an integer, and the range in which to choose, has to be thee same as the number of items on the list, i.e. the number of jokes. The command Math.random() handles the selection of a random number in the interval [0 ; 1[, and by multiplying with the number of items found using Joke_lmnt.length (like this: Math.random() * Joke_lmnt.length), the possible random numbers will be in an interval equivalent to the number of items/jokes.

The list, when done using getElementsByTagName(), starts with numner 0, i.e. if you have 10 items/jokes, you have the numbers 0 to 9, not 1 to 10. The calculations using Math.random() * Joke_lmnt.length will give a decimal number, and we need an integer, so we have to round off. To make the numbers fit, we round down the numbers, using Math.floor(), so we start at 0 and the possible numbers matches the number of items/jokes. Then it looks like this:

<SCRIPT TYPE="text/javascript">
xmlDoc=loadXMLDoc("Jokes.xml");

var Joke_lmnt = xmlDoc.getElementsByTagName("text_string");
NumberOfElements = Joke_lmnt.length;
RandomNumber = Math.floor(Math.random() * Joke_lmnt.length);

</SCRIPT>


Now we need a routine fetching the joke with the number that was just generated. We do that by parsing the list using a for, that starts at 0 and goes through the numbers to the maximum number of items/jokes. When it reaches the number on the list equivalent to the random number, i.e. i==RandomNumber (note that there has to be two equal tos), it writes the item/joke using a document.write(). Otherwise it does nothing.

To avoid having the text just appearing there in the middle of everything else, we place it in a DIV using document.write() before and after. Then the finished code looks like this:

<SCRIPT TYPE="text/javascript">
xmlDoc=loadXMLDoc("Jokes.xml");

var Joke_lmnt = xmlDoc.getElementsByTagName("text_string");
NumberOfElements = Joke_lmnt.length;
RandomNumber = Math.floor(Math.random() * Joke_lmnt.length);

document.write("<DIV>");
   for (i = 0; i < NumberOfElements; i++)
      if (i==RandomNumber) {
         document.write(Joke_lmnt[i].firstChild.nodeValue);}
      else { }
document.write("</DIV>");
</SCRIPT>


On the screen it looks like this (try updating the page by pressing F5):



In this example, the code was done direcly on the page. If you want to have it done as an external script, as seen in the example above, you can just do that instead.


If you need multiple random values

You can find yourself in a situation where you need two or more random numbers. If the values are allowed to be the the same, you just copy the variable RandomNumber and call it something else. It may, however, not always be acceptable, and in that case, you put in a loop to handle this.

In practice you start by generating two random values as described above. Here we call them RandomNumber1 and 2.

After this we create a loop using while. We test whether RandomNumber1 and 2 are equal (RandomNumber2 == RandomNumber1, note that there is 2 equal tos). As long as RandomNumber1 and 2 are equal, it has to repeat generating RandomNumber2.

Then the code looks like this:

<SCRIPT TYPE="text/javascript">
var Joke_lmnt = xmlDoc.getElementsByTagName("text_string");
RandomNumber1 = Math.floor(Math.random() * Joke_lmnt.length);
RandomNumber2 = Math.floor(Math.random() * Joke_lmnt.length);

while (RandomNumber2 == RandomNumber1) {
   RandomNumber2 = Math.floor(Math.random() * Joke_lmnt.length);
   }

</SCRIPT>


From here you can get the elements you want (or whatever else you may need the two numbers for).