Articles in the ‘Tips & Tricks’ Category

Events with MooTools - Element, Class, Delegation and Pseudos

Written By Arian Stolwijk, on Monday, March 28th 2011, 2:18pm

One of the most useful and common part of MooTools is its Events Type. There are two Event usages: Element and Class. Element.Events is probably the most known because that’s probably one of the first things you’ve used when you started using MooTools. Furthermore, MooTools More 1.3 Events.Pseudos has been introduced to give even more power and control over Events and with Event Delegation can give your page a massive performance boost. This blog post will give you a deeper insight into all components.

(more…)

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.

More than Meets the Eye: Form Validator

Written By Aaron Newton, on Friday, April 30th 2010, 3:09pm

Continuing with my “More than Meets the Eye” series, today I want to talk to you about the MooTools More Form.Validator. There was a comment left on my last post in this series (about Form.Request) specifically requesting that I cover this relatively complex plugin that’s useful for telling users about the validity of data they enter into forms before they send them.

Getting Started with Validators

The main class you need to concern yourself with is the Form.Valdiator class itself which provides methods that apply specific rules to inputs to see if they are valid. You can then choose how you want to inform your users that they need to address these problems, but that’s not the job to Form.Validator (though it is the job of Form.Validator.Inline, which we’ll cover in a bit).

Let’s talk little bit about the rules that are applied. Form.Validator allows you to define rules that test the state of an input and return true or false - true if the input passes the validation rule, and false if it doesn’t. Here’s a simple example:

Form.Validator.add('doesNotContainTheLetterQ', {
        errorMsg: 'This field cannot contain the letter Q!',
        test: function(field){
                return !field.get('value').test(/q/,'i');
        }
});

The above code adds a global validator that allows you to assert that the input doesn’t use the letter Q. The arguments are the validators’ key and then an object that contains an error message to show the user should they encounter the error, and a function that is passed the input as an argument. This function inspects the value or, really, anything you like, and then returns true or false.

The key you give your validator is important. At any time you can validate a field against any validator by using this key as a reference by doing:

myFormValidator.test(key, input[, warnOnly]);

The first two arguments are the important ones here; the key of your validator and the input to test. Where things get interesting are when Form.Validator does this for you. By giving your input that key as a css class name, you tell Form.Validator to validate that field with this validator. In this manner you can quickly and unobtrusively decorate your inputs with the requirements and validate the form. If something goes wrong with your JavaScript, your form will submit as normal. Here’s a really simple example:

The alerts aren’t pretty, but you can see how our validator is now applied when you submit the form.

Form.Validator ships with several validators listed in the documentation. These include simple stuff like required that just validates that the user put something - anything - in the input. But there are also validators for email addresses, only letters, dates, urls, etc. The key is you can write your own - you don’t need to wait for us to release something for you to make use of it. There are an extended list of validators in Form.Validator.Extras that include some edge cases. Things like validating that two inputs have the same value (like an email verification for example).

Using Validators with Arguments

It’s also possible to configure validators with data unique to the input. For example, let’s say you want to have an input with a minimum length validator - the user must type in at least 5 characters. You could write a validator called minimum5 or whatever, but then you’d have to duplicate it for any other character length. For this purpose, Form.Validator allows you to assign values to the input, like so:

<input type="text" name="username" class="minLength:10" id="username"/>

These values - the 10 and 100 values in the example above - get passed along as JSON decoded values to the validator. Here’s what that looks like:

Form.Validator.add('minLength', {
    errorMsg: function(element, props){
        return 'Please enter at least {minLength} characters (you entered {length} characters).'.substitute({minLength:props.minLength,length:element.get('value').length });
    },
    test: function(element, props){
        if (props.minLength != null) return (element.get('value').length >= props.minLength;
        else return true;
    }
});

As you can see, the error message (which in our previous validator was just a string - the message) can also be a function which is passed the input and then any properties defined in the HTML. The fact that the message can be a function allows you to include information not only about how the validator is configured but also other information, like some aspect of the value the user actually entered. The test is also passed along these p roperties of course which allows you to make the properties a condition of the test. We could, in theory, rewrite our doesNotContainTheLetterQ validator to accept an argument about the character (or, better yet, characters) that we want to disallow:

Form.Validator.add('doesNotContain', {
    errorMsg: function(field, props){
        return 'The value you input cannot contain any of the following letters: ' + props.doesNotContain;
    },
    test: function(field, props){
        if (props.doesNotContain)
            return !field.get('value').match(new RegExp('[' + props.doesNotContain + ']', 'i'));
        else return true;
    }
});

Note that the properties defined have to be JSON decodable, so you can’t have your input like this:

<input type="text" class="doesNotContain:qz"/>

Instead you’d have to quote the string:

<input type="text" class="doesNotContain:'qz'"/>

Here’s our example:

The base Form.Validator class comes with a plethora of options and events. You can configure it to validate inputs whenever they change (on blur), or to only show one error at a time (serial). You can tell it to ignore hidden fields (those that are not visible, there’s no point in validating inputs with type=”hidden”) and disabled inputs. There are numerous useful methods that let you run the entire validation routine on the form (.validate()), reset all the errors (.reset()) or validate / reset a specific field (.validateField() and .resetField()). You can pause the validator and resume it (.stop() and .start()) as well as ignore / un-ignore a specific field (.ignoreField() and .enforceField()) and more. There’s even an element method that lets you validate a form (Element.prototype.validate).

Form.Validator.Inline - the “Pretty” One

Now that we’ve covered the basics of how Form.Validator works, let’s consider the fact that our examples so far have been rather ugly (who wants alert messages?). MooTools More ships with a default implementation that smoothly displays messages inline, right after the input: Form.Validator.Inline. This class is the “pretty” version of Form.Validator but don’t think of it as the only game in town. You can easily implement your own “pretty” version without a lot of effort. If you want to put errors in a popup or fade them in over the entire screen or play a sound it doesn’t matter. The base Form.Validator class is there for you.

Looking at the Form.Validator.Inline implementation, you’ll find all the same options and methods from Form.Validator along with a few extras that control how your messages appear. For instance, by default, the validation rules show up immediately after the input. This requires a bit of forethought in how you structure your HTML. If your input is inline with something else (like a submit button), validation errors are going to change that when they appear (because they are divs, which by default are block level elements).

The only real option that Form.Validator.Inline has to offer is whether or not to scroll to errors (useful if your form is long and will likely cause the user to scroll to the submit button). Here’s a simple example, building on our previous one:

As you can see, the error message slides in, but it breaks our layout a bit. Let’s do some CSS work to make this look a little nicer.

It’s not The Sistine Chapel but it does look nicer. Our error doesn’t appear to break our layout anymore either.

As a final example, I’ll show you a version that extends Form.Validator.Inline to put the validation messages in tips that popup pointing at the input. Here’s a demo:

If you want you can check out the source on github and download it with its dependencies on Clientcide.

Go Forth and Validate

Overall the purpose of Form.Validator is not to be the only solution for displaying validation messages to your users, but rather a flexible solution for client side form validation on which to build. You can extend it and manipulate it to display messages in any way you choose - and you should!. The default “pretty” implementation - Form.Validator.Inline - is just one way to use the class. In my opinion Form.Validator is one of the classes in MooTools More that shows off the power of MooTools’ object oriented design, allowing for a great deal of flexibility and reuse.

Thanks to Lloyd for suggesting this edition’s topic. If there’s a plugin in MooTools More you’d like me to focus on next time, by all means, make a suggestion in the comments.

Aaron Newton is a contributor to MooTools and the principal developer of MooTools More. He is the author of the book MooTools Essentials as well as the Mootorial online MooTools tutorial. He posts (rarely these days) at his blog Clientcide.com and (much more often) on Twitter as anutron. He works for Cloudera, (which is hiring, by the way).

Get friendly with the Natives

Written By Ryan Florence, on Tuesday, March 23rd 2010, 9:48pm

Have you extended a Native lately? It’s an incredibly helpful thing. Often people write ugly functions that take a string or whatever as an argument and return some manipulation of the string. Extending natives is a great way to do the same thing, but it is much prettier (aka: explicit, readable, easier-to-debug.)

The Difference:

I’ve seen stuff like this:

fn1(fn2(10, fn3('house')));

Hard to figure out what’s happening. Instead you can write code like:

fn3('house').fn2(10).fn1();    

A Useful, Real Example, zeroPad

I’ve used this in a couple scripts, it takes a number and returns a string with zeros padded in front: 123 becomes ‘000123’. Really handy for filenames and the like. Here’s the ugly version:

Functionally Based Example

function zeroPad(num, zeros){
  zeros = zeros || 3;
  var str = '' + num;
  zeros.times(function(){ str = '0'+str; });
  return str;
};

// usage
doSomething(zeroPad(document.getElementById('myInput').value, 3));

Native Extentions Based Example

Number.implement({
  zeroPad: function(zeros){
    var str = '' + this;
    zeros.times(function(){ str = '0'+str; });
    return str;
  }
});

// so that it works on both numbers and strings
String.implement({
  zeroPad: function(zeros){
    return this.toInt().zeroPad(zeros);
  }
});

// usage
$('myInput').get('value').zeroPad(3).doSomething();

Side by Side:

doSomething(zeroPad(document.getElementById('myInput').value, 3));
// vs
$('myInput').get('value').zeroPad(3).doSomething();

Awesome? Yes. You can do the same thing to:

Some say extending natives is a bad idea. Personally, I think it’s awesome—but this topic is a sore spot for some. Extending natives is a feature of javascript itself that any general application framework like MooTools is entitled to use. There could be an entire article dedicated to this topic but this article isn’t it. This article is simply here to show how to use this handy feature.

Flippin’ Sweet Array methods

Arian Stolwijk created this amazing gem: Array.Math. Code samples often tell the story faster:

[2,5,1,6].sum(); // 14
[2,5,6,2].product(3); // [6,15,18,6]
[9,12,15].quotient(3) // [3,4,5]

This is all made possible by extending the Array native, see?

    Array.implement({

        sum: function(start,length){
            var sum = 0, 
                start = start ? start : 0,
                length = length ? length : this.count()-start;
            length = start ? length + 2 : length;
            for(var i=start;i&lt;length;i++) sum += this[i];
            return sum;
        },

        product: function(p){
            var arr = $type(p) == 'array';
            return this.map(function(entity,i){
                return arr ? (entity * p[i]) : (entity * p);
            });
        },

        quotient: function(q){
            var arr = $type(q) == 'array';
            return this.map(function(entity,i){
                return arr ? (entity / q[i]) : (entity / q);
            });
        },

        // and a whole lot more awesome ...

    });

Quick Tips

  • this is the number or string, or whatever, when inside the method.
  • Return something that makes sense (usually this).
  • You can implement several methods all in the same code block.

This is just one more great tool to help keep your code organized and readable.

MooTools 1.1 Upgrade Helper (beta)

Written By Moo Tools, on Thursday, December 31st 2009, 3:03pm

Users wishing to upgrade any large site from MooTools 1.1 to 1.2 can sometimes find it difficult. The API for 1.2 changed quite a bit, so without help upgrading your code can be fraught with danger.

Our solution is an upgrade helper that will allow you to replace your old MooTools 1.1 code with 1.2 code by logging deprecated methods to the console and telling you what needs to be changed.

The upgrade helper also attempts to automatically convert 1.1 calls to 1.2 calls. However, this helper is not really meant to be a compatibility script so much as a script designed to help you migrate your code. In almost all cases methods that have been deprecated or have had their API altered will provide feedback to the console when they are called. Ideally, developers will put this script into their environment with MooTools 1.2, use their application and change all the calls that throw warnings, then remove the upgrade helper from their environment.

Using the Upgrade Helper

You can download the upgrade helper on the MooTools Download Page along with current build of MooTools built for it. This companion library has all the functionality found in MooTools 1.1 (Drag, Accordion, etc. - some of these plugins moved out of MooTools Core and into MooTools More in 1.2).

Simply replace MooTools 1.1 with MooTools 1.2, include the upgrade helper, then include your site’s code. Browse your site with a browser that provides a console API (we recommend Firefox with Firebug) and take note of the warnings thrown (note, you can adjust the logging; see the readme). Address these in your code base until you cannot find any more, then remove the upgrade helper. You have now an upgraded website, and you can use the plugins in the Forge!

If you still have warnings after you have finished converting your code, have a look at the documentation for 1.1 and 1.2 and also the source code in the upgrade helper. Most changes are simple, but may require a change of arguments. There are a few breaking changes but in the vast majority of cases these should not affect you. A complete list of the changes between 1.1 and 1.2 can be found in the readme of the github upgrade-helper repository.

Feedback, Help, and Resources

The upgrade helper is being released as a beta for now. We’ve written and run tests against the browsers we support but the real world usage of MooTools will be the real test. As such, we hope that you, the MooTools community, will help us polish this script, by letting us know what features on your sites don’t work. Bugs can be filed using the github issues for the repository.

Arguably, this is something we should have provided long ago. Going forward, we’ve pledged to make all releases 100% backwards compatible for all documented methods and features.

Should you require any guidance or assistance, you can, as always, find us in the #mootools IRC channel or post in the MooTools Google Group.

Last of all, massive thanks to Nathan White and David Isaacson, for their early work on this. In the last few weeks the MooTools Dev team has spent a lot of time making and testing this upgrade helper, but these guys kicked this off with their contributions and they are most appreciated.