Super-fast Intro to Arrays in Javascript
An array in Javascript is a list of items. It can contain numbers, text (strings), objects, etc. Arrays are defined, typically, like this:
var myNumberArray = [1,2,3,4,5];
var myStringArray = ['George', 'Henry', 'Bob', 'Harold', 'Zeke'];
This method declares the array and initializes it with data in the same step. Arrays are defined as comma-separated lists of items.
You can also define an array and then push items onto the array later like so:
var myNumberArray = new Array();
var myStringArray = [];
myNumberArray.push(1);
myNumberArray.push(2);
myStringArray.push('George');
myStringArray.push('Henry');
Notice I've used two different methods for declaring the two arrays. While both are valid, most Javascript developers prefer the approach I took with myStringArray.
Building Arrays in XMod Pro
Because arrays are lists of items, they lend themselves nicely to the repeating nature of XMod Pro's templates. Much as you can create an Unordered List or Table and rows, you can also create Javascript templates. Basically any text that repeats could be generated.
So, let's replicate this in an XMod Pro template. For this example, we'll pull a list of Display Names from the users table. Since your site may have a lot of users, we'll limit the returned results to the top 10. To begin, let's write out our shell - the non-repeating parts of our array declaration.
<script type="text/javascript">
var arrNames = [
];
</script>
Next, we'll add in the XMP template code. There are a couple of ways you can lay this out. This is one option:
<xmod:Template UsePaging="False" UseAjax="False">
<ListDataSource CommandText="SELECT TOP 10 DisplayName FROM vw_Users ORDER BY DisplayName" />
<HeaderTemplate>
<script type="text/javascript">
var arrNames = [
</HeaderTemplate>
<ItemTemplate>'[[DisplayName]]'</ItemTemplate>
<SeparatorTemplate>,</SeparatorTemplate>
<FooterTemplate>
];
</script>
</FooterTemplate>
</xmod:Template>
All of the XMod Pro code should be pretty familiar to you. What we've done is add our SQL command to the <ListDataSource>
. Inside the <HeaderTemplate>
tag we've added the opening, non-repeating code from the shell. In the <FooterTemplate>
tag, we've added the closing, non-repeating code from the shell. The <ItemTemplate>
tag contains JUST the code that repeats with each record - the DisplayName in our case, surrounded by single quotes. One tag you may not use often, but which is very handy in this case is the <SeparatorTemplate>
tag. Its contents will be inserted after each <ItemTemplate>
- but only if there are more records coming. In practical terms, that means we can build a comma-delimited list without a trailing comma.
After running your template, inspect your code. Mine looks like this:
<script type="text/javascript">
var arrNames = [
'Franklin Delano Roosevelt','George Washington','SuperUser Account','Test User 1','Test User 2'
];
</script>
We've just created a perfectly valid array of first names from the DB. Now if you're a stickler for pretty code we can do that too, but there's a trade-off. The rendered code may look nicer, but your XMP code will be harder to read... your call:
<xmod:Template UsePaging="False" UseAjax="False">
<ListDataSource CommandText="SELECT TOP 10 DisplayName FROM vw_Users ORDER BY DisplayName" />
<HeaderTemplate>
<script type="text/javascript">
var arrNames = [</HeaderTemplate><ItemTemplate>'[[DisplayName]]'</ItemTemplate><SeparatorTemplate>,</SeparatorTemplate>
<FooterTemplate>];
</script>
</FooterTemplate>
</xmod:Template>
After the changes, my rendered code looks like this:
<script type="text/javascript">
var arrNames = ['Franklin Delano Roosevelt','George Washington','SuperUser Account','Test User 1','Test User 2'];
</script>
The good news is because XMod Pro allows you to have multiple <xmod:Template> tags in a single template, you can define multiple, data-bound arrays. You'll need to modify the code a bit but not by too much:
<script type="text/javascript">
<xmod:Template UsePaging="False" UseAjax="False">
<ListDataSource CommandText="SELECT TOP 10 DisplayName FROM vw_Users ORDER BY DisplayName" />
<HeaderTemplate>
var arrNames = [
</HeaderTemplate>
<ItemTemplate>'[[DisplayName]]'</ItemTemplate>
<SeparatorTemplate>,</SeparatorTemplate>
<FooterTemplate>
];
</FooterTemplate>
</xmod:Template>
<xmod:Template UsePaging="False" UseAjax="False">
<ListDataSource CommandText="SELECT TOP 10 UserId FROM vw_Users ORDER BY DisplayName" />
<HeaderTemplate>
var userIds = [
</HeaderTemplate>
<ItemTemplate>[[UserId]]</ItemTemplate>
<SeparatorTemplate>,</SeparatorTemplate>
<FooterTemplate>
];
</FooterTemplate>
</xmod:Template>
</script>
In this last example we've created 2 arrays. The format of the XMP code is the same, except we moved the opening <script>
and closing </script>
tags so they now contain the <xmod:Template>
tags. The result is:
<script type="text/javascript">
var firstNames = [
'Franklin Delano Roosevelt','George Washington','SuperUser Account','Test User 1','Test User 2'
];
var userIds = [
5,4,1,2,3
];
</script>
Again, you can adjust the rendered output as we did before. I'll leave that as an exercise for people who have too much time on their hands.
Pushing Items Onto the Array
Declaring and initializing an array is quite useful. But there are times when you need to declare your array elsewhere in the page. Or maybe it is already declared by another library or module. In that case you can simply modify your template to use the Array's push method like so:
<script type="text/javascript">
<xmod:Template UsePaging="False" UseAjax="False">
<ListDataSource CommandText="SELECT TOP 10 DisplayName FROM vw_Users ORDER BY DisplayName" />
<ItemTemplate>arrNames.push('[[DisplayName]]');</ItemTemplate>
</xmod:Template>
</script>
As you can see, this greatly simplifies our code. Because the <script> tag contains the <xmod:Template>
tag, we only need an <ItemTemplate>
tag. Inside that template, we just output the Javascript code to push the DisplayName onto the array. Simple and clean.
But what about JSON data?
Good question.... one I'll answer in another article.... Nah... why make you wait? Creating an array of JSON objects is not much different than the other arrays we've been creating.
Since JSON objects typically have move that one property, I've expanded the SQL to return the DisplayName and UserId for each user.
Now, when most non-programmers say "JSON", what they really mean is Object Literal Notation. At one level, the two are similar in look, but JSON is a subset of Object Literal Notation. In JSON, property/key names must be delimited by quotes as must any textual value. Numeric and boolean values should not be quoted. For more, I refer you to the JSON docs (http://www.json.org/js.html).
Our JSON object is going to look like this:
{
"name": "Franklin Delano Roosevelt",
"id": 5
}
So, because we're creating an array of these objects, the comma will go afer the closing curly brace }. Here's the code:
<script type="text/javascript">
<xmod:Template UsePaging="False" UseAjax="False">
<ListDataSource CommandText="SELECT TOP 10 DisplayName, UserId FROM vw_Users ORDER BY DisplayName" />
<HeaderTemplate>
var arrUsers = [
</HeaderTemplate>
<ItemTemplate>{ "name": "[[DisplayName]]", "id": [[UserId]] }</ItemTemplate>
<SeparatorTemplate>,</SeparatorTemplate>
<FooterTemplate>
];
</FooterTemplate>
</xmod:Template>
</script>
The only substantive change we're making is the object definition which, as before, happens in the <ItemTemplate>
tag.
Now, before you send me email complaining that your code doesn't work, remember that JSON has strict syntax. Because you're surrounding your text with quotes, if any of your data contains quotes, they have to be escaped before being rendered. The same goes for other characters like line feeds. In other words, you'll want to process your text in SQL server before sending it to XMod Pro. Of course, XMod Pro provides an easier way to do this - <xmod:JsonFeed>
. If you're calling a feed with this tag as its base, XMod Pro will take care of all that encoding for you.... but that's for another article.