Follow me: @D_mitar

Most read posts recently



Feb 2nd 2012 × Using overloadSetter / overloadGetter to make flexible functions in mootools

This is a really helpful feature of MooTools that a few people know and use. Basically, there is a pair of 2 Function prototypes called ‘overloadGetter‘ and ‘overloadSetter‘. They are very simple in what they can provide. Say, you have a function that is a private property setter in a Class that takes 2 arguments: key & value. After a while, you may get bored having to call it all the time for every property you wish to add or having to write object loops for longer updates.

By defining using the Function decorator overloadSetter, you can – without any code adjustment – make your single key/value pair setter take an object and automatically iterate through the properties for you.

Similarly, by using the decorator overloadGetter, you can pass on multiple properties to retrieve that you are interested in – and it will return a single object with all your properties of interest as key.

Pretty cool?

Here’s a real world example. Let’s say, you are making a MVC Model Class that you’d like to use to deal with data objects and dispatch events.

(function() {

    // private real setter functions, not on prototype, see note on .set
    var _set = function(key, value) {
        // needs to be bound the the instance.
        if (!key || typeof value === undefined)
           return this;

        // no change? return. better rely on _.js _.eq but this is crude and works for primitives.
        if (this._attributes[key] && this._attributes[key] === value)
           return this;

        if (value === null) {
            this._attributes.delete(key); // delete = null.
        }
        else {
            this._attributes[key] = value;
        }
        // fire an event.
        return this.fireEvent("change:" + key, value);
    }.overloadSetter();   

    this.Model = new Class({

        _attributes: {}, // initial private object,

        Implements: [Options, Events],

        initialize: function(data, options) {
            data && typeOf(data) === 'object' && this.set(data);
            this.setOptions(options);
        },

        set: function() {
            // call the real getter. we proxy this because we want
            // a single event after all properties are updated
            _set.apply(this, arguments);
            this.fireEvent("change");
        },

        get: function(key) {
            // and the overload getter
            return (key && typeof this._attributes[key] !== undefined)
                ? this._attributes[key]
                : null;
        }.overloadGetter()

    });

})();

// now make an abstraction of your Model class for users
var User = new Class({

    Extends: Model,

    _attributes: {
        name: "Please enter your name",
        email: "Enter your email address"
    }

});

// initialise your User Model with default data and set some property change events
var user = new User(null, {
    "onChange:email": function(value) {
        // can dispatch to controller/view the change
        console.log("new email now is", value);
    },
    "onChange:name": function(value) {
        console.log("new name now is", value);
    },
    onChange: function() {
        console.log("data has changed!");
    }
});

// let's test this. initial set via single value set:
user.set("email", "dimitar@securemail.com");

// now let's try multiple properties at the same time:
user.set({
    "email": "dimitar@securemail.com",
    "name": "coda"
});

// get the name
console.log(user.get("name")); // coda;

// get multiple properties in a single object
console.log(user.get(["name","email"]));
// Object { name="coda",  email="dimitar@securemail.com"}

View and play with this on http://jsfiddle.net/dimitar/39x7T/

That’s about it. Please note that this Class was only created for the purposes of a demo and is not meant to be used in a real MVC pattern – look at Composer.js (for MooTools), Backbone.js or Ember.js – formerly Sprout Core – if you are interested in doing serious event-based application development.


Feb 2nd 2012 × MooTools in a distant future: how to write to better survive the changes

You may have already heard this, or maybe not. But this won’t change the fact that javascript is changing and the way people write it and specifically, how they write the libraries, modules and widgets we all share and use is slowly being edged towards an AMD pattern. This stands for Asynchronous Module Definition, pioneered by the DOJO framework with a one main goal in mind: being able to define and load any module and its dependencies asynchronously. Whereas it is not a standard yet, it is considered as a step towards the module system proposed in ES Harmony. I also won’t go into any possible shortcomings of this dependency system and the dangers of remote dependencies (bloat), that’s an entirely different topic.

Anyway, with that out of the way, what is the single most important thing to take away from the message that MooTools 2.0 (aka, Milk) will be AMD compliant? In order to become truly modular and compartmentalised into the small parts that have been the building blocks of the framework for years, MooTools is going to stop changing and extending the javascript natives Types’ prototypes. Only then does it guarantee that any of its modules can co-exist with any other AMD module without any conflicts.

When I say ‘stop changing’ natives, it does not mean it won’t ever modify an existing method (Function.bind comes to mind as an example) but in all likelihood, it won’t be doing much of that. You can start to treat bits of it like a microjs library. Even mix-n-match your favourite components from around the web, eg, take Class and use it on top of jQuery (if you really have to!), or bring Sizzle into MooTools instead of Slick with the utility functions of Underscore.js.

Sounds like a win. Now, the unpleasant part. Not being able to modify Element.prototype (for example) means a likely end to code like this:

document.id("someid").addEvent("click", function(e) {
    this.addClass("open");
    var divsWithImages = this.getElements("li").filter(function(el) {
        return !!el.getElement('img');
    });
    // I know you can use a reverse combinator selector for this. not the point.
});

Though the team will probably do a function wrapper like jquery that can allow the above in part, document.id() will stop returning the element itself but will return a function instead. The modified code may look the same but how it’s interpreted will be different. For instance, this.addClass(“open”); won’t work at all. Instead, it will probably need to go through either $(this) / document.id(this) or via the native Type or Slick.

Basically, all Array, Element, String etc methods (see the popular MooTools Types) are still available on the native object instead. You _could_ write the above like so:

Element.addClass($(this), 'open');

The Array / Elements.filter can be called like this:

var divsWithImages = Array.filter(document.id(this).getElements("li"), function(el) }
    return !!document.id(this).getElement("img");
});

Although I honestly have no idea what the new API will really look like, one thing is certain: even as of MooTools version 1.4.3 (time of writing), you can dual use most methods on the host object or through the prototype.

eg,

var strTest = "dimitar was here";
// old way via String.prototype
console.log(strTest.capitalize()); // Dimitar Was Here
// new way, same result.
console.log(String.capitalize(strTest));

It’s a small shift in the way we write code. Since both work already, I would advise you to use the latter one so you have less of a refactor to do if you ever hope to drive your existing code base with the future versions of mootools.

Now, how do you create a String method that will work with both the prototype and the host object? Seems simple. The scope is the host object so, here is a sample rot13 method that can work as both…

(function() {
    var n;
    String.implement({
        rot13: function() {
            return String(this).replace(/[a-z]/gi, function(match) {
                return String.fromCharCode((n = match.charCodeAt() + 13) > 122 || n < 104 && n > 90 ? n - 26 : n);
            });
        }
    });
})();

console.log(strTest.rot13());
console.log(String.rot13(strTest));

I suspect Type.prototype will become protected in the sense that implement will not affect them, making implement behave like Object.extend does at present. If you swapped .implement for .extend in the above code block and then String(this) to String(namedArg), you get a simple and safe-ish native type method.

This is all too similar to how you extend the Object Type (prototyping Object itself has always been a bad idea as everything in javascript inherits from Object):

// extend, not implement.
Object.extend({
    getPropertiesCount: function(object) {
        var props = [],
            hasOwnProperty = this.prototype.hasOwnProperty;
        for (var prop in object) {
            if (hasOwnProperty.call(object, prop))
                props.push(prop);
        }
        return props.length;
    }
});

console.log(Object.getPropertiesCount(this)); // return your global variables count!

I am certain these will not be the only changes but they will certainly be the most difficult to get used to. On the upside, there will be a compatibility layer as usual, including the ability to ‘install’ the prototype methods where possible. Even so, don’t be naive and write code that won’t outlive mootools 1.x without a lot of changes.

In conclusion, things are looking up for MooTools – it is headed in the right direction, even if slowly. My only gripe with this is that we need somebody from the core team to give news of how the release of Milk is coming along every so often. So we can get ready or even help…

*note: parts of this post are based on hearsay and sporadic data from various mootools members over IRC and Twitter. Don’t go writing any books on MooTools 2.0 just yet, you may even have to change the title (cough-Aaron-cough)*


Jan 12th 2012 × A larger MooTools logo

I had to look around and find an up-to date mootools logo of a decent size and I couldn’t find one. Hence, I took an old and small AI file and updated it to the current colours, ending up with the logo at 25cm and 300 DPI!

Whereas I won’t post this size here (see note below), I rendered a smaller version to an alpha PNG. Hope it helps someone to create great MooTools inspired fan art, wallpapers or whatever.

mootools logo - large

**note: apparently, use of the MooTools logo is under the strict control of Valerio Proietti, aka Kamicane. I am not going to post any high res logo and if you end up using this one, you really ought to ask for his permission.**


Dec 25th 2011 × substitutePath – a string method that recursively replaces values from an object

Originally, this was meant to be released as something for String.Extras in mootools-more as an idea by Oskar, coined by myself with input from csuwldcat – but it seems that the pull request is not going anywhere so I will release it here instead.

The idea is to extend the behaviour of String.substitute to be able to work with deep properties of the object that is being passed on, which means easier templating without having to flatten objects beforehand so the properties of interest are on the same level.

View on github as per pull request

String.implement({
    substitutePath: function(object, regexp) {
        return String(this).replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name) {
            if (match.charAt(0) == '\\') return match.slice(1);
            if (object[name] != null) return object[name];

            var retStr = "",
                path = name.split('.'),
                length = path.length,
                sub = object;

            if (length <= 1)
                return retStr;

            for (var i = 0; i < length; i++) {
                if((sub = sub[path[i]]) == null) return retStr;
            }
            return sub;
        });
    }
});

The use goes like this:

var foo = "this is a bar called \"{lame.bar.name.here}\"";
var objOK = {
    lame: {
        bar: {
            name: {
                here: 0
            }
        }
    }
};

var objFail = {
    lame: {
        bar: {
            lame: {
                here: "hello"
            }
        }
    }
};

console.log(foo.substitutePath(objOK)); // works
console.log(foo.substitutePath(objFail)); // should fail
console.log(foo.substitutePath({foo:"bar"})); // should fail
console.log("this is a {bar}".substitutePath({bar:"success"})); // should work (legacy as .substitute);

Here's the jsfiddle you can play with: http://jsfiddle.net/dimitar/RtBMm/

Please note that the above will only deal with non-primitives (numbers, strings) and will fail if the key matches a function or an object. To address that, I have made a change in the jsfiddle (still being tested) that deals with it in a reasonable way here: http://jsfiddle.net/dimitar/RtBMm/6/ - though calling the function with the scope of the object and w/o parameters may not be ideal, it should cover a large percentage of cases. For any other types, I guess it will do a .toString() anyway.


Dec 24th 2011 × New mootools plugins released on github/forge

Time to wrap up the year, I think. I released 2 more small plugins of mine on github and the MooTools forge.

mooTagify
GitGub project page: https://github.com/DimitarChristoff/mooTagify
Forge link: http://mootools.net/forge/p/mootagify

A plugin for small tag lists input. Also, provides an ajax auto-completion sub-class that can be used as a standalone anyway.

Screenshot:

Example with ajax tag completion: http://fragged.org/mooTagify/Demo/
The plugin is quite easy to setup and you can style it via CSS only or via the many options available to the 2 classes that run it.

Modal.BootStrap
GitGub project page: https://github.com/DimitarChristoff/Modal
Forge link: hhttp://mootools.net/forge/p/modal_bootstrap

This is a combination of several things: the flexible modal markup experiment by @csuwldcat (Daniel Buchner from Mozila), implemented in the Modal.Base class and the Modal.BootStrap class.

The BootStrpa itself (not to be confused with Twitter’s BootStrap) provides a flexible implementation of content in the Modal window through HTML5 element mark-up only, including support for ajax links, grabbing content from elements on the page or setting pure text, even image support (pseudo-lightbox). It also works with location.hash so you can have page.html#terms_and_conditions as a link, if there’s a matching element managed by the BootStrap instance on the page.html, it will open it automatically for you. The modal will ALWAYS stay in the middle of the screen, it has support for responsive design with minimum width and max width as well as support for CSS3 transitions over js morphing of style properties (if available). Very useful for things like terms and conditions, privacy policies, quick contact forms, questionnaires and so forth. It also has support for buttons in the footer with custom events fired in the instance, so its flexible for scripting.

Screenshot:

Example with location.hash: http://www.fragged.org/dev/Modal/Demo/#interview2

Merry Christmas, everyone and a Happy New Year – unless I release anything in-between.


Nov 9th 2011 × Using MooTools class mutators to log method calls

When you are debugging a huge web app, comprised of many classes and many methods, it can be really tedious and difficult. Having to go and edit code and add `console.log` calls all over the place is hardly productive and can involve a lot of typing. Fortunately, you can use a lesser known feature of MooTools called ‘Class Mutators’ to change the prototype of your class and automatically log calls to your methods of interest.

// define the mutator as 'Monitor', use as Mointor: ['methodname', 'method2'...]
Class.Mutators.Monitor = function(methods){
    if (!this.prototype.initialize) this.implement('initialize', function(){});
    return Array.from(methods).concat(this.prototype.Monitor || []);
};

Class.Mutators.initialize = function(initialize){
    return function(){
        Array.from(this.Monitor).each(function(name){
           var original = this[name];
           if (original) this[name] = function() {
               console.log("[LOG] " + name, "[SCOPE]:", this, "[ARGS]", arguments);
               original.apply(this, arguments);
           }
        }, this);
        return initialize.apply(this, arguments);
    };
};

What this does is defines a class mutator called ‘Monitor’, which can be added to any class declaration. It accepts either a single method name (as string) or an array of method names that you would like to log.

In your class, this will look like this:

var foo = new Class({

    Monitor: 'bar',

    initialize: function() {
        this.bar("mootools");
    },

    bar: function(what) {
        alert(what);
    }

});

var f = new foo();
f.bar.call({hi:"there from a custom scope"}, "scope 2");

When the code runs, you will see in your console the 2 calls to the monitored method, indented by method name, the scope and the arguments it has received.

This can save your life. Play on jsfiddle: http://jsfiddle.net/BMsZ7/2/ :)


Nov 2nd 2011 × mooGrowl: a lightweight growl style class for mootools 1.4

There was notiMoo and I am sure there have been other javascript/mootools Growl notification solutions already. Yet, none of them were CSS3 and mootools 1.4 friendly, so I created a new Class instead.

Check out mooGrowl on GitHub
https://github.com/DimitarChristoff/mooGrowl

View the demo on jsfiddle:
Full screen or normal jsfiddle

Screenshot of some Growls:

no

Oct 31st 2011 × mooPlaceholder revisited: a flexible placeholder input solution for IE and older browsers

Creating some javascript that can mimic the HTML5 behavior of a placeholder= attribute on an input element can be simple. Unfortunately, getting a single solution you can work with that fits all browsers and have little overhead to work with is not that easy.

The following are the requirements when making it universal:

  • work as progressive enhancement for browsers that don’t support it only (feature-detect)
  • respect initial values
  • be able to attach and detach the placeholder behavior on demand

Since the progressive enhancement only works by using the value property of the input in older browsers, it presents a problem for form validation. You don’t want your form submission to go through with fields that have the placeholders assigned as the actual values. This is not what the native placeholder behavior is so you need a way to remove the enhancement prior to your form validation and submission. You also need to be able to re-attach it, should validation fail and submission be stopped pending user action.

http://jsfiddle.net/dimitar/bYQ8P/ is the updated mooPlaceholder class. I suggest you view it in IE6/7/8 to actually experience the difference. It should act *exactly* how the placeholder works in say, FireFox 7. To get around the jsfiddle issues with IE, view it under the full /show/ url here

So, to recap: if you want to validate a form that has child elements managed by the class, you’d do the following when using my Class:

var placeholders = new mooPlaceholder().attachToElements(); // add it.
formElement.addEvent("submit", function(e) {
    // remove placeholder while validating...
    placeholders.detachFromElements();
    // run validation code here.
    if (failed) {
        e.stop(); // stop submit
        placeholders.attachToElements(); // restore placeholders
    }
});

I think this overhead is quite acceptable, considering. It can be done automatically on your form submits by doing a element.getParent(“form”) but this way is also fine. Hope it helps somebody.


Oct 18th 2011 × Working with dynamic Class names in MooTools

This is somewhat trivial but is also useful and is a common question that a lot of people ask. The problem is in 2 parts: How to instantiate a Class based upon a dynamic name/variable and how to identify the Class name that has created a MooTools Class instance (the prototype, really).

First of all, to make a dynamic instance based upon a variable name, you simply need to know the name and context of execution (scope) of the Class you want to instantiate.

// define the class in the current scope / global object
this.foo = new Class();

// define the class in a namespace
var namespace = {
    foo: new Class()
};

// get the variable class name we need to use from any source into a variable...
var dynamic = 'foo';

// make the instances
var instance1 = new this[dynamic]();
var instance2 = new namespace[dynamic]();

So far, so good. This is pretty standard javascript and is self explanatory.

The harder bit comes when you have an instance and you are trying to find what Class name it is an instance of. We will create a small function that can help:

function getClassNameOfInstance(mootoolsClassInstance, context) {
    // query the context (this or custom object) for the instance we are working with
    return Object.keyOf(context || this, mootoolsClassInstance.constructor);
}

// use it on the global object
console.log("instance1 is: ", getClassNameOfInstance(instance1)); // foo

// use it on the namespace object
console.log("instance2 is: ", getClassNameOfInstance(instance2, namespace)); // foo

This function will check the context object for the constructor of the instance and return the ‘key’ if it matches, which will be MooTools Class name.

I hope it helps someone out there. Check it on JSFIDDLE: http://jsfiddle.net/dimitar/S4rR6/2/


Jul 6th 2011 × Lazyloading multiple sequential javascript dependencies in MooTools

We all know and love Asset.js from MooTools-more. It affords you lazyloading by providing Asset.javascript, Asset.image, Asset.images and Asset.css. However, sometimes you need more precision when bringing in external scripts as dependencies.

Hence I created my own Asset.javascripts – based losely on a coupling of Asset.images and Asset.javascript but providing sequential asynchronous loading.

Asset.javascripts = function(sources, options) {
    // load an array of js dependencies and fire events as it walks through
    options = Object.merge({
        onComplete: Function.from,
        onProgress: Function.from
    }, options);
    var counter = 0, todo = sources.length;

    var loadNext = function() {
        if (sources[0])
            source = sources[0];

        Asset.javascript(source, {
            onload: function() {
                counter++;
                options.onProgress.call(this, counter, source);
                sources.erase(source);

                if (counter == todo)
                    options.onComplete.call(this, counter);
                else
                    loadNext();
            }
        });
    };

    loadNext();
};

Eg. usage with Arian’s DatePicker class, which uses multiple files that need to be loaded in their right order:

if (!window.Picker) {
    new Asset.javascripts([
        "/js/mylibs/Locale.en-US.DatePicker.js",
        "/js/mylibs/Picker.js",
        "/js/mylibs/Picker.Attach.js",
        "/js/mylibs/Picker.Date.js"
    ], {
        onComplete: function() {
            new Asset.css("/js/mylibs/datepicker.css");
            new Asset.css("/js/mylibs/datepicker_dashboard/datepicker_dashboard.css");

            doDates();
        }
    });
}
else {
    doDates();
}

Have fun.