30 Days of Mootools 1.2 Tutorials - Day 3 - Intro to Using Arrays

- Troy

Intro to Using Arrays in Mootools 1.2

If you haven’t already, be sure and check out yesterday’s tutorial - Day 2 - Selectors

In the last tutorial, we looked at selectors, many of which created arrays (a special list that gives you a lot control over the contents). Today, we are going to take a look at how to use arrays to manage DOM elements.

The Basics

.each();

.each(); is your best friend when dealing with arrays. It provides an easy way to iterate through a list of elements, applying whatever script logic is necessary. For example, lets say you wanted to call one alert box for every div within a page:

$$('div').each(function() {
    alert('a div');
});

With this html, the code above would fire two alert boxes, one for each div.

<div>One</div>
<div>Two</div>

.each(); doesn’t require you use $$. Another way to create an array (liked we talked about yesterday), is to use .getElements();.

$('body_wrap').getElements('div').each(function() {
    alert('a div');
});
<div id="body_wrap">
    <div>One</div>
    <div>Two</div>
</div>

Still another way to accomplish the same task is to send the array to a variable, then use .each(); on that variable:

//first you declare your variable by saying "var VARIABLE_NAME"
//then you use the equal sign "=" to define what goes in that variable
//in this case, an array of divs
var myArray = $('body_wrap').getElements('div');
 
//now, you can use that array variable just like an array selector
myArray.each(function() {
    alert('a div');
});

Finally, you are going to want to separate out your function from the selector and .each();. We are going to talk more in depth about how to use functions in tomorrow’s tutorial, but for now, we can create a very simple one like this:

 
var myArray = $('body_wrap').getElements('div');
 
//to create a new function, you declare a variable just like before, then name it
//after the equal sign you say "function()" to declare the variable as a function
//finally, you place your function code between { and };
var myFunction = function() {
    alert('a div');
};
 
//here you just call the function inside .each();.
myArray.each(myFunction);

Note: When you call a function like we did here inside of .each();, you do not put any quotes around the function name.

Making a Copy of an Array

$A

Mootools provides a way to simply copy an array with the $A function. Lets set up another array with a variable like we did above:

//create your array variable
var myArray = $('body_wrap').getElements('div');

To create a copy of the array:

//create a new variable, called "myCopy," then assign the copy of "myArray" to your new variable
var myCopy = $A(myArray );

Now myCopy contains the same elements as myArray.

Grab a Specific Element within an Array

.getLast();

.getLast(); will return the last element within an array. First we set up our array:

var myArray = $('body_wrap').getElements('div');

Now we can grab the last element within the array:

var lastElement = myArray.getLast();

The variable lastElement now represents the last element within myArray.

.getRandom();

Works just like .getLast();, but will get a random element from the array.

var randomElement = myArray.getRandom();

The variable randomElement is now represents a randomly chosen element within myArray.

Add an Element to an Array

.include();

With this method, you can add another item into an array. Simply place the element selector within .include(); and attach it to your array. With the following html setup:

<div id="body_wrap">
    <div>one</div>
    <div>two</div>
    <span id="add_to_array">add to array</span>
</div>

we can create an array like we did before by calling all the divs that are children of ‘body_wrap.’

var myArray = $('body_wrap').getElements('div');

To add another element to that array, first add the element you want to include to a var, then use the method .include();.

//first add your element to a var
var newToArray = $('add_to_array');
 
//then include the var in the array
myArray.include(newToArray);

Now, the array contains both the divs and the span element.

.combine();

Works just like .include();, except it lets you add an new array to an existing existing array without having to worry about duplicate content. Say we had two arrays from the following html:

<div id="body_wrap">
    <div>one</div>
    <div>two</div>
    <span class="class_name">add to array</span>
    <span class="class_name">add to array, also</span>
    <span class="class_name">add to array, too</span>
</div>

We could then build the following two arrays:

//create your array just like we did before
var myArray= $('body_wrap').getElements('div');
 
//then create an array from all elements with .class_name
var newArrayToArray = $$('.class_name');

Now, we can use .combine(); to combine the two arrays, and the method will deal with any duplicate content so we don’t have to.

//then combine newArrayToArray with myArray
myArray.combine(newArrayToArray );

Now myArray contains all the elements from newArraytoArray.

Examples

Arrays let you do iterate through a list of items, applying the same chunk of code to each one. In this example, notice the use of “item” as a placeholder for the current element.

//creates an array of all elements within #body_wrap with the class .class_name
var myArray = $('body_wrap').getElements('.class_name');
 
//first lets create a new element to add to our array
var addSpan = $('addtoarray');
//now lets create an array to combine with our array
var addMany = $$('.addMany');
 
//now we can include the new span
myArray.include(addSpan);
//and combine our addMany array with myArray
myArray.combine(addMany);
 
//create a function to go through each ITEM in the array
var myArrayFunction = function(item) {
	//item now refers to the current element within the array
	item.setStyle('background-color', '#eee');
}
 
//now you call the myArrayFunction for EACH item within the array
myArray.each(myArrayFunction);
<div id="body_wrap">
    <div class="class_name">one</div><!-- this has gray background -->
    <div>two</div>
    <div class="class_name">three</div><!-- this has gray background -->
    <span id="addtoarray">add to array</span>  <!-- this has gray background -->
    <br /><span class="addMany">one of many</span>  <!-- this has gray background -->
    <br /><span class="addMany">two of many</span>  <!-- this has gray background -->
</div>

To Learn More…

This tutorial does not begin to cover the wonderful things you can do with arrays, but hopefully it has given you an idea of what Mootools has to offer. To find out more about arrays, take a closer look at:

Download a zip with everything you need to get started

Includes a simple html file, the Mootools 1.2 core, an external JavaScript file, a css file and the example above.

Tomorrow

Tomorrow we will look closer at functions and how to use them in Mootools.

Tutorial Request or Questions

For the next few days we are going to continue to cover the basics, but over the next few weeks we will move toward more complex projects, and I would love to hear what subjects are of the most interest to you all. Feel free to drop a note with any suggestions, comments or questions. Thanks and I hope you find this useful.

Bookmark and Share

Comments (21) Trackbacks (2)
  1. Andreas


    Some notes to this part. $A also converts a html-collection (getElementsByTagMame())into an array, so you can use it with the mootools array function. Mootools use the build in js functions if the browser supports it, like FF, Safari and Opera. IE doesn't have implement this function so mootools emulate them. If it comes to performance bottlenecks it's better to use a simple for loop then each. At least one cool thing at each() is that every step of the loop runs in a function and have its own scope instead of a for loop where the scope is the main function.
  2. Brian


    ".....notice the use of “item” as a placeholder for the current element."

    Is "item" just a javascript keyword? And similarly, I have seen "this" used in javascript. Are these both similar?
  3. Vin Thomas


    WOW! Tons of info, but it definitely is starting to make sense. I have dabbled in plenty of frameworks, but mainly I have just copied code.

    Thanks!
  4. Sam


    @Brian - 2

    Item isn't a protected/special keyword, it's just the name of the parameter that the function is using. The example code could just as easily be :

    var myArrayFunction = function(purplepeopleeaters) {
    purplepeopleeaters.setStyle('background-color', '#eee');
    }

    The value in item itself is being passed by .each as input.
  5. Troy


    @1 Thanks for providing some insight into this area Andreas. Hope you will stick around and continue to fill out the details.
  6. Mauro De Giorgi


    There's an error in the include() section:

    The span id in the html code is called "addtoarray" and the code search for "another_id":

    var newToArray = $('another_id');
  7. Sam


    Got it, thanks for catching that
  8. Tim B


    The external javascript file is commented improperly, and throws an error in IE 6, and perhaps other browsers.

    It should look like this:

    /* JavaScript Document
    *Place functions within this document
    Call functions within the dom ready in the html page */

    Thank you for the excellent tutorials; I'm going to try and work my way through each.
  9. Troy


    Thanks Tim, I'll be sure to correct that.
  10. David


    Hi,
    Great tutorials! Really cool stuff! I was hoping that you could point me in the right direction if i wanted to do the following:
    I have tabbed panel form that is basically like a multi-step form (because its huge), and on the last tab i wanted to show a list of the form's name/value pairs, so that the user can review their information. I typically use sessions in ColdFusion to do this, but i'm trying to not have to submit the form before the last tab. Is there a way to loop through the form values and display them using mootools? Any suggestions would be greatly appreciated. I've been looking for about 2 hours now for how to write out a value of a form element with javascript and i'm not having any luck. I've found tons for showing items in alert boxes and other form elements, but not straight writing it to the screen in a td or div using innerhtml or something.

    THanks,
    David
  11. Troy


    David, you can use element.setProperty('value', newValue) for an input field.

    You can get the values in the same way, element.getProperty('value');

    element.setProperty('text', whatever); element.setProperty('html', whatever);

    So you could have something like (when user clicks on tabs, transfer values from input to a container element).

    I hope this answers your question.
  12. David


    Troy,
    Yes! I figured that after reading a few of these and thinking about it. I put a long list like this:

    var eName = $('eventName').get('value');
    $('showEventName').set('text',eName);

    Long and tedious as there are alot of form elements, but it works. my only issue now is i have both links and tabs links that do paging for me between the layers, and thus far have been using only the tabs to fire the function that passes the values from above. I'm trying to wrap my head around the array and get elements functions but its not working so far.

    var arrayElements = $$('tabs', 'nextPrevButton').getElements();
    arrayElements.each(function()) { .addEvent('click', addFormValues);

    tabs and nextPrevButtons are the two items that i would like to add the onclick event to so that the get/set values fires. Any thoughts?

    Thanks again for these amazing tutorials!

    David
    }
  13. David


    Think i go it!
    $$('#tabs', '.nextPrevButton').addEvent('click', addFormValues);

    seems to work but is this proper?
  14. Troy


    David, I'm glad that it's coming along. To answer your questions, first I would make sure that the $$ selector has proper css selectors, (if you want an id, you will need '#idname', a class needs '.classname' etc). Also, be sure to check out the day on creating functions. You can create a function where the id for the input and container are parameters, then just call that function over again with the new id parameters. Regarding the rest of your question, it's kind of hard to envision it without seeing it, but if you want to drop me a note with a url, I can check it out.
  15. Troy


    :) Nice! Looks like you got it right as i was responding, lol.
  16. David


    One more thing.. if you don't mind :)...

    when a person is at the bottom of the form and they try to submit it and its not valid yet, it just stays there. Is there a way to make the focus go to the top of the page?

    Thanks,
    David
  17. Troy


    You can say inputEl.focus();. Add that inside an event to put the focus in inputEl.
  18. Jeff Benetti


    Fantastic tutorials, I'm on day 3, looking forward to working through the rest of the series. What a great gift to the community, you explain things very well.
    I hope to take my new knowledge and develop a library for CodeIgniter.

    Thanks,
    Jeff in Beautiful Nova Scotia
  19. David


    Hi Troy,
    Still can't get that focus() to work for some reason. I'm using $('#contentBody').focus();, where the contentBody is the outer most div. I place it at the end of my addFormValues() function which fires when the form button is submitted. Shouldn't this force the focus on to the top where contentBody div starts?

    Thanks again,
    David
  20. yaniv


    Thanks alot for the tutorial.
    i've been reading many guids, and thie series really helps me out. i'm new to JS and the stuff is explained really good, so i catch both the basic JS issues and also mootools.
    thanks you!
  21. Muhammmed AK


    hi,

    Any one can help me?


    following script doesn't work!






    div
    div
    div
    div
    div
    div
    div
    div
    div
    div
    div



    -------------------------------------

    var myArray=$('Wrapper').getElements('div');
    var test=myArray.getLast();

    var myArrayFunction=function(item)
    {
    item.setStyle('background-color','#669933');
    }

    test.each(myArrayFunction);


Leave a Reply