Articles by ‘Sean McArthur’

The Journey Toward More 1.3

Written By Sean McArthur, on Wednesday, September 22nd 2010, 2:17pm

MooTools has always prided itself with the quality of its developer community, and the MooTools development team has always highly valued the opinion and input of the thousands of users who continually support the framework. With this in mind, we’ve decided to provide everyone with a quick update on the recent work that the More team has been doing. Specifically, the meta things about More; the things we do to make working on MooTools More better and better.

MooTools More Team Has Grown and Been Busy

With the help of our two newest developers, Arian and Tim, the MooTools More team has been working hard to get More up and running with Core 1.3. Aside from updating old Core API calls, they’ve been fixing a lot of the Lighthouse bugs, as well as providing new improvements like Event.Pseudos, Locale and more.

The last of the 1.2.x More releases has been a priority since the Core 1.2.5 release. It will come with a lot of bug fixes and a few new features. The hold up is converting all of More’s tests to use the new process described below. As such, it looks like More 1.2.5.1 and More 1.3.0.1 will likely be released together.

Testing MooTools

To help with this increased development—and to make sure less bugs squeak by—we have set up a new testing environment using the wonderful Windmill testing framework. An example of the new sandbox environment can currently be found at http://review.mootools.net:9876.

A couple of us have also been hard at work improving the testing throughout all the MooTools projects, but you’ll just have to wait and see the awesome details in a later article.

Contributing is Getting Easier!

With the release of GitHub’s new Pull Requests system, we’ve found that they fit very well into the MooTools development workflow. The new system makes it easier for the developers to review pull requests, and makes the discussions associated with them public.

Because the MooTools community is made up of awesome developers who are more than happy to share their work and to give back to the project, we realized that this new pull request feature could be very helpful in accepting contributions from the community. As such, we are encouraging all of you to send us your pull requests for review and possible inclusion in the Core and More repositiories.

Big Things Happening…

We hope that you’re as excited as we are with what’s cooking on the MooTools development front. We’d like to hear your opinions, comments and suggestions in the comments section below, so don’t hesitate to drop a line or two.

We also invite everyone to visit our official Github repository and drop by the official #mootools IRC Channel on Freenode. MooTools also has a twitter account that you can follow for more news and updates.

And stay tuned—we have something very special coming in the next few weeks that will hopefully blow your minds.

Now off for a chocolate milk!

Setting Up Elements

Written By Sean McArthur, on Thursday, June 10th 2010, 11:16pm

Once you know how much easier it is to get elements all around, you should take the time to learn how MooTools has provided a simple access API around the browser quirks for Elements. And on top of it, we’ve extended this API to things that you don’t normally find on Elements. And as cool as it is, you can easily add your own bits with ease.

Get Who? Set What?

On Elements, theres only 3 getters/setters that you need to worry yourself with: get/set, getStyle/setStyle, and store/retrieve (we’ll ignore getProperty for now).

Get/Set

The most commonly used are Element#get and Element#set. They will first check the Element.Properties object to see if a specific getter/setter exists, before defaulting to getProperty or setProperty. So for instance, you can get the href of a link, or you can get the text of an element, which will get the node value in a cross browser fashion.

<a id="myAnchor" href="/blog">Blog</a>
<div>All my <span>text</span></div>

$('myAnchor').get('href'); // '/blog'
$('myDiv').get('text'); // 'All my text'

You can do as you would expect with the setters in the same way.

$('myAnchor').set('title', 'MooTools Blog'); //sets title attribute
$('myDiv').set('text', 'other text'); //sets the innerHTML

For now, let’s just look at the other methods, and we’ll take a look at how this works later so you can add to it yourself.

Setting with Style

The other commonly used pair of methods are Element#getStyle and Element#setStyle. These should hopefully be self explanatory. Their benefit is that they normalize certain styles the browsers are inconsistent about, such as opacity.

Elemental Properties

Let’s take a look at an example that MooTools itself defines. The style property is easier to remember and read than using cssText, so that’s what MooTools does for us.

Element.Properties.style = {

    set: function(style){
        this.style.cssText = style;
    },

    get: function(){
        return this.style.cssText;
    }

};

Seeing how the style object is setup, you can easily create your own. Given a Person class, and the given HTML, we could decide it would beneficial to be able to get the instance of a Person from an element.

<div class="person person_3">
    Sean
</div>
<p>Hello</p>

Say we were to want to get a Person instance when we have this element. We would define the property on Element.Properties.

Element.Properties.person = {

    get: function() {
        var id = this.className.match(/person_(\d+)/)[1];
        if(id) return Person.getById(id);
    },

    set: function(person) {
        this
            .addClass('person')
            .addClass('person_'+person.id)
            .set('html', person.name);
    }
};

Now we can use our familiar get and set methods.

$('TestPerson').get('person'); // returns Person instance of ID 3.
$('OtherTest').set('person', new Person('John')); //turns the paragraph into a person
// <p class="person person_4">John</p>

Let’s just Store that

The third pair of methods that MooTools defines for elements is Element#store and Element#retrieve. Woah woah woah. What? You’re telling me you can get properties, and you can retrieve them? What the heck guys?

Don’t worry, it’s pretty easy to know and understand the difference once I explain it. get and set are the most common methods, and default to element attributes, like I said. In many other places, such as when you use el.get('tween'), the MooTools teams made the getter call retrieve for you. You’ve been accessing it, without knowing it.

OK, great Sean. Why should I care how you give me the values?

I hear you. You see, most of the getters/setters are used to access attributes. But what happens you want to get at or set some other kind of property. What if you want to set an actual object, or a function to the Element. I guess you could JSON encode and create a custom attribute, but that’s not good practice. And you lose out on any class info of the object, in case it was an instance of something.

These methods also help with an issue that arises when you try to store something like an Event object or an instance of something else that refers to the Element in question. Certain browsers don’t handle the circular references that well if you were to set el.prop = { someEl: el }. It can leave nasty memory leaks.

If you really want to know, behind the scenes, MooTools keeps a storage object that is totally separate from any element. Every element created gets assigned a unique id, and that id is used as a key on the storage object.

Regardless, you don’t have to do anything special for store/retrieve to work. Using our above example, it would work like so:

$('TestPerson').store('person', new Person('Sean'));
$('TestPerson').retrieve('person'); //returns the exact same Person instance

These two common pairs of methods actually have a third method that relates to each of them, which allows the destruction of each respective data location. These methods are Element#erase and Element#eliminate.

Apply this yourself

This all sounds great, I’m sure. Now when you’re writing your own classes and plugins, you can be sure to use the pre-packaged properties. However, it’s much more powerful when you can find a useful property to add that relates to your own plugins.

Sean McArthur is a software developer at Blazonco.com who is madly in love with MooTools. Most of his contributions involve sharing tips and information about MooTools (and programming in general) at his blog and on Twitter.

A Better Way to use Elements

Written By Sean McArthur, on Friday, March 19th 2010, 5:41pm

Javascript development in the browser is all about the Elements. Manipulating the DOM happens every few lines of code. It’s important enough that some libraries provide little more than DOM enhancements. Not to worry though, MooTools provides greatly in this area as well.

$ and $$

Most of you probably know the two document methods getElementById and querySelectorAll; because if you do, you understand how we select elements with MooTools methods. For those of you that don’t, you provide an ID string of an element in to getElementById, and a CSS selector string to querySelectorAll. The functions $ (which is an alias to document.id, see this post on Dollar Safe Mode for details) and $$ are basically equivalent to getElementById and querySelectorAll, respectively. Of course, since it’s MooTools, they’re more than that.

The dollar function, if given a string, will basically call getElementById on the document. If passed an element, it will just return the element, and if you pass an object with a toElement method, it will try to convert it to an element (we’ll explore that more a couple sections down). A key difference you’ll find between MooTools’ dollar function and jQuery’s is this: MooTools’ $() will only ever return 1 Element, and it will return null if no matching element is found. This means unless you’re absolutely 110% certain the element will exist, you’ll need to check the returned value before starting to call Element methods on it.

    var loginEl = $('Login');
    if (loginEl) {
            loginEl.fade('in');
    }  

The MooTools Team prefers two separate methods for the selecting elements; to remove any doubt about what a certain function call may be returning, we have one method for individual elements and another for multiple elements. In this case, it’s preferable to be explicit, instead of relying to ambiguous auto-magic. When we see $, we expect an element if it exists. When we see $$, we expect an array of elements (which, as you know, an array can always be empty). The double dollar function has some neat tricks that are explained in its own section below.

All this talk about Elements, but only about how to select them. MooTools also provides an excellent Element construction API.

new Element()

With vanilla JS (mmm, vanilla…), you’d use document.createElement whenever you wanted to create and add a new element to the DOM. MooTools tries to make the JavaScript API more pleasant to use; part of that is a more consistent and easy to use syntax and part of it is using more Object-Oriented programming practices. It feels a lot more OO when creating objects using the new keyword, whereas the standard way is more procedural.

It turns out that every element you could create inherits from the Element prototype. Specifically, the elements you create through document.createElement would be HTMLDivElement, or HTMLParagraphElement, or whichever element you create. Like I said, they all inherit from the base Element prototype, and then HTMLElement, and so on. MooTools extends the base Element class, so that all elements receive some MooTools love.

MooTools augments the Element native, providing a super-duper sweet constructor. You can provide the tag name, and then an object of properties to set on the new element. The returned object is of the same type as the $ method mentioned above. The properties you can set are fairly extensive, so check out the documentation to learn more about them, but here’s a demonstration.

toElement

The dollar method provides another function: converting the instance of class into an element(-al?) form. This is similar to a toString function, which converts objects into strings when needed. You can define a method in a class called toElement, and return an element to “represent” the instance. Let’s take a look at a snippet from a Person Class:

Several extensions in MooTools More take advantage of this, like Form.Request, Form.Validator, HtmlTable, and others. And many plugins in the Forge use this approach as well. This means that after creating an instance of one of these classes, you can just hold on to the instance in your code. Whenever you want to affect the element that the instance is controlling, you just use $(instance) to retrieve it.

Aaron even cooked up a ToElement mixin, and wrote a bit more about this over here.

Elements

I pointed out earlier that $$ returns an array-like object containing Elements. It actually returns an object called exactly that: Elements. Behind the scenes, MooTools gets an array of all the elements that meet the selector (so it’s still an array), and then extends the array with all the Elements methods. Why would we want that?

All the methods that MooTools adds to the Element native are added to the Elements class as well. You can do some pretty nifty chaining because of this. First of all, you don’t have to check that it didn’t return null. This is because any method you call on Elements, will loop through the array and try to call the method on each individual element. Even with an empty array, the loop won’t cause an error. And any method you call that would normally return a value, will return an array of the values from each element. An example should make this clearer:

    //assigns a click event to all A tags
    $$('a').addEvent('click',  function(e) {
            e.preventDefault();
            alert(this.href);
    });  

    //gets all divs with an id set, and then returns
    //an array of the IDs  sorted alphabetically
    var ids = $$('div[id]').get('id').sort();  

    //gets all divs with a UL immediately inside
    //and assigns a class name to  the divs
    $$('div &gt; ul').getParent().addClass('has-list');

While you could put together long chains acting on all the elements you’ve selected, I’d advise against this. It certainly looks cool, and will work fine one or 2 methods out on the chain. But every method call will cause another loop through all the elements. If you’re doing a lot of things to every element, you might as well do it all in a single pass. I’ll show you what I mean.

    //this would loop through each time at addEvent, addClass, and fade
    $$('li  a').addEvent('click', function(e) {}).addClass('alertable').fade('in');  

    //whereas this will only cause 1 loop
    $$('li a').each(function(link)  {
            link.addEvent('click', function(e) {
                     alert(this.title);
            });
            link.addClass('alertable');
            link.fade('in');
    }); 

Still, when doing something simple, you can skip the each call, since Elements will handle that for you.

Concluding

MooTools provides a lot of expressive power when working with the DOM. It’s consistent API makes it a snap to add events, change styles, create elements and more. The object oriented nature of its implementation makes it so that you can extend Elements for your own purposes. Look forward to my next post where I’ll talk about extending Elements in various ways and cover best practices for when you decide to bend Elements to your own will.

Sean McArthur is a software developer at Blazonco.com who is madly in love with MooTools. Most of his contributions involve sharing tips and information about MooTools (and programming in general) at his blog and on Twitter.