Most read posts this month



Mar 10th 2010 × Cross-domain AJAX calls via YQL as proxy and mootools JSONP

I wrote this a while back when I needed to do pseudo AJAX calls to a remote host. Due to XSS restrictions and security policies, a normal XMLHttpRequest (XHR) call is not allowed to work across domains or even sub-domains. But Yahoo’s YQL interface kindly lets you GET any URL (which also means being able to submit via GET), irregardless of whether the domain is local or not.

Here is how it works. You need mootools (also download mootools-more as this clan will extend Request.JSONP which is a part of mootools-more).

Request.YQLajax = new Class({
    // gets basic info such as country and latitude data
    Extends: Request.JSONP,
    options: {
        log: !true,
        url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22{location}%22&format=xml"
    },
    initialize: function(location, options) {
        this.parent(options);
        if (!location)
            return;

        this.options.url = this.options.url.substitute({location: encodeURIComponent(location)});
    },
    success: function(data, script) {
        this.parent(data, script);
    }
});

// example use to fetch BBC's page
new Request.YQLajax("http://www.bbc.co.uk/", {
    onSuccess: function(data) {
        $("result").set("html", data.results);
    }
}).send();

You can see this in action on mooshell or play with it below. Happy cross-domain ajax-ing.


Mar 4th 2010 × Getting latest tweets through mootools JSONP

Nothing like being egocentric so here’s what you can do to add latest tweets of a particular user to your site through mootools. This class totally `forked` from a post by AppDen (Scott Kyle) so feel free to give him some love, he deserves it for being such a bright spark. You can also “play” with this live on JSFiddle

Request.twitterAPI = new Class({
    // return json data with latest tweets form a particular user
    Extends: Request.JSONP,
    options: {
        target: $empty(),
        tweetBits: {
            textClass: "tweetBody",
            dateClass: "tweetDate"
        },
        maxTweets: 4,
        autoLink: true,
        url: "http://twitter.com/statuses/user_timeline/{user}.json"
    },
    initialize: function(user, options) {
        this.parent(options);
        this.options.url = this.options.url.substitute({user: user});
        this.element = document.id(this.options.target);
        if (!this.element)
            return;

        this.element.set("html", "Loading tweets...");
    },
    success: function(data, script) {
        this.element.empty();
        this.parent(data, script);
    },
    showPost: function(post) {
        var creationDate = Date.parse(post.created_at).format("%x %X");
        new Element("div", {
            "class": this.options.tweetBits.textClass,
            "html": this.options.autoLink ? this.linkify(post.text) : post.text
        }).adopt(new Element("div", {
            "class": this.options.tweetBits.dateClass,
            "html": creationDate // + " via " + post.source.replace("\\",'')
        })).inject(this.element);
    },
    addPosts: function(response) {
        if (!response.length || !this.element)
            return;

        response.each(function(post, i) {
            if (i < this.options.maxTweets)
                this.showPost(post);
        }.bind(this));
    },
    linkify: function(text){
        // modified from TwitterGitter by David Walsh (davidwalsh.name)
        // courtesy of Jeremy Parrish (rrish.org)
        return text.replace(/(https?:\/\/[\w\-:;?&=+.%#\/]+)/gi, '$1')
            .replace(/(^|\W)@(\w+)/g, '$1@$2')
            .replace(/(^|\W)#(\w+)/g, '$1#$2');
    }
});

// create an instance
new Request.twitterAPI("D_mitar", {
    target: "myTweets", // target element to 'host' the tweets
    onComplete: function(data) {
        this.addPosts(data); // add all posts to element.
    }
}).send();

Additionally, you can style the tweets by using 2 classes for the element:

div.tweetBody {
    line-height: 1.1;
    font-family: arial;
    font-size: 12px;
    margin-bottom: 10px;
}

div.tweetDate {
    font-size: 10px;
    color: #500;
    text-align: center;
    padding-top: 4px;
}

That’s it, it’s that simple. Happy tweeting.


Feb 14th 2010 × Detect adblocking software through mootools and have a fallback strategy

Being able to check if website adverts were blocked is of some importance. As browser plugins such as AdBlock Plus and the likes are getting better all the time, less and less of your adverts get served up. Hence, my simple solution that can try and recover some of the lost revenue.

Google adwords code can be wrapped into a plain DIV tag without a set width/height, letting any content injected into it by Google dictate its size. Through a basic Element prototype shortcut, called Element.adCheck(), you can check if the size has remained less than expected (aka, the AD got blocked).

Element.implement({
    adCheck: function(options) {
        var options = $merge({
            delay: 3000,
            message: "<center>It looks as if my Adwords did not display<br />I am just a programmer that needs to feed their hungry child and wife, please disable AdBlock or whatever clever advert blocking software you are running on my site.</center>",
            minHeight: 20,
            minWidth: 20
        }, options);

        this.store("timer", (function() {
            var coords = this.getCoordinates();
            if (coords.height.toInt() < options.minHeight || coords.width < options.minWidth) {
                this.set("html", options.message).fade(0, 1)
            }
        }).delay(options.delay, this));
        return this;
    }
});

// check it for a div with id="as":
$("as").adCheck();

// check it for all divs with class 'myads'
$$("div.myads").adCheck({message: 'please disable adblock'});

// use alternative adverts instead
$("as").adCheck({message:"<a href='/signup.php'><img src='/img/signupbanner.gif'>"});

To run this, you need mootools 1.2+ core only. You could also extend the above code to .pass() a function callback so you can execute a proper ‘onAdvertFailed’ event.

Just a thought, but wouldn’t it be nicer if AdSense could serve adverts through JSONP that you can parse and embed clientside? It won’t be mainstream but it could really screw with current AdBlocking methods…


Feb 11th 2010 × Get a url’s tweet / retweet count via tweetmeme api and mootools JSONP

I needed to get retweet counts as data, as opposed embedding the standard widget that tweetmeme supply.

Turning to their API instead got me joy initially. After a stressful few minutes with a javascript label exception was taking place, it transpired that the tweetmeme API was not returning valid JSON within i’s deignated callback wrapper. Instead, it came back as simple JSON. I was about to give up and write a PHP/curl wrapper when I noticed their ‘format’ is called jsonc whereas I was requesting ‘json’. Oh well, works fine now.

Through extending the mootools’ Request.JSONP class, it’s a manner of seconds to get things going:

Request.tweetmeme = new Class({
    // return json data with extended information of a place / location.
    Extends: Request.JSONP,
    options: {
        url: "http://api.tweetmeme.com/url_info.jsonc?url={location}",
    },
    initialize: function(location, options) {
        this.parent(options);
        this.options.url = this.options.url.substitute({location: location});
    },
    success: function(data, script) {
        this.parent(data, script);
    }
});

// example use
// get retweets for all posts on a page and update the counter. URL in the rel property of the markup.
$$("div.twitterBar").each(function(el) {
    var url = el.get("rel");
    new Request.tweetmeme(url, {
        log: true,
        onSuccess: function(data) {
            el.set("html", data.story.url_count);
        }
    }).send();
});

I hope this helps somebody – once again, how easy it is to extend JSONP and get things done in mootools.


Jan 10th 2010 × The mootools plugins repository ‘forge’ is now live, at last

Long time without updates but I have been away since mid December. Long story short, went to Bulgaria with the best of intentions to ski a little and ended up “enjoying” the warmest winter this country has had in over 20 years instead. Meanwhile, folks back home in London reported to be freezing their privates in some serious sub-zero temperatures. Figures…

Anyway, things of consequence since my departure start with the advent of the mootools forge – finally a meaningful way to distribute plugins for the framework. I should see if any of my code snippets are worth releasing (can’t all be David Walsh, can it…)

Another notable addition to my bookmarks has been jsfiddle – it’s basically like Zalun’s mooshell but on steroids – adding support for all major frameworks you can fiddle with out there, most excellent and handy when refactoring between mootools and jquery and vice versa.

Finally, there has been a great compatibility layer for upgrading mootools 1.11 to 1.2.x – check out the official blog post here. I am now officially out of _technical_ excuses to do with upgradingand refactoring all the javascript at webtogs, so it’s going to be a manner of time after I get back.

The biggest joke of the year thus far has been the realisation that this little page (fragged.org) has now become the 2-nd listing on the google SERPs for ‘mootools blog’, trailing the official team blog only. Take that, David Walsh! Oh yeah, and a shiny new PR4 out of the blue, not a bad end to the year. With mootools 1.3 in the pipelines as well as mootools 2.0 – 2010 promises to be an quite exciting as well, looking forward to it.

P.S. Here’s another new ‘#mootools heavy blog’ just launched by a person I have come to respect a great deal over on the mootools mailing list check out Ryan Florence’s blog


Nov 24th 2009 × Lemmings javascript sprite animation with pseudo parallax (through mootools)

This was supposed to be my Friday Fun post but it got to where it’s at on the following Monday instead. Having never tackled sprite animation before, this has been a learning experience anyway (on the principles of animation also).

I think the result is fairly adequate – a moving lemming in a world that changes atmospheric effects dependent on the time of day, complete with parallax-like effect relative as counter to the lemming’s movement.

Oh, yes. The lemming can also be quite moody–hates being bothered. Which is fine, you can blow him up too. Enjoy and click below:
lemmings parallax animation screenshot

P.S. This will feature as the header of fragged.org’s new wordpress theme which is almost completed now. So, a little taster of things to come…
P.P.S. Thanks to crisp for the original DHTML lemmings and to holy.pt for his vigorous testing and advice.


Nov 18th 2009 × Snow flakes for your site? Try mooSnow – a javascript class that just snows

Just pulled out the old textSnow class foer 1.11 and rewrote it for 1.2.4. Anyway, head over to the demo page, it has all the info you need.


Oct 20th 2009 × mootools 1.2.4 released. finally.

Only 2 weeks late, which by software development standards is ‘dead on’, mootools 1.2.4 and 1.1.2 are officially released.

Amongst the more-exciting changes for me (aside from the the many fixes and additions to -more), JSON.stringify and JSON.parse native methods and DomReady always firing before load event (this had been plaguing me for a while on IE).

And, last but not least, a Depender class for lazy-loading of required components that can get your class working. Brilliant – on-demand javascript. All-in-all, a very nice and worthwhile drop-in replacement and enhancement over the old 1.2s.

Just a word of mention, 1.1.2 is a fix in the mootools 1.11 branch that will enable IE8 and gecko (firefox) detection. Not bad…


Sep 25th 2009 × Extending the Request.JSONP class to fetch geolocation data from YQL and others

Here’s a novel idea (stolen from AppDen’s Twitter feed fetch class) – extend the mootools-more’s JSONP class and setup some quick and easy geolocation lookups through pidgets.com and YQL (yahoo query language).

Here they are, 3 mini classes. First one uses the client’s IP address (or an optional ip supplied by options) to fetch geolocation info from http://geoip.pidgets.com/. The second instance fetches extended information on a place / city by location from Yahoo’s geoplaces DB, including things like local district, council authority, county and so forth, something that I find useful when creating quick signup forms for users and PAF lookups are not in the budget. The final class was simple test to fetch relevant timezone info of any latitude + longitude combination. It offers local time, offset from GMT or DST etc, but nothing that Date.get(“gmtoffset”) can’t accomplish anyway).

Request.geoLocation = new Class({
    // gets basic info such as country and latitude data
    Extends: Request.JSONP,
    options: {
        ip: $empty(), // default is user but you can lookup anything.
        url: "http://geoip.pidgets.com/?format=json",
    },
    initialize: function(options) {
        this.parent(options);
        if (this.options.ip.length)
            this.options.url = this.options.url += "&ip=" + this.options.ip
    },
    success: function(data, script) {
        this.parent(data, script);
    }
});

Request.getPlaceInfo = new Class({
    // return json data with extended information of a place / location.
    Extends: Request.JSONP,
    options: {
        url: "http://query.yahooapis.com/v1/public/yql?q=select * from geo.places where text='{location}'&format=json",
    },
    initialize: function(location, options) {
        this.parent(options);
        this.options.url = this.options.url.substitute({location: location});
    },
    success: function(data, script) {
        this.parent(data, script);
    }
});

Request.timeZone = new Class({
    // return local timezone related date from geo coordinates
    Extends: Request.JSONP,
    options: {
        url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%3D'http%3A%2F%2Fws.geonames.org%2Ftimezone%3Flat%3D{latitude}%26lng%3D{longitude}'&format=json"
    },
    initialize: function(latitude, longitude, options){
        this.parent(options);
        this.options.url = this.options.url.substitute({latitude: latitude, longitude: longitude});
    },
    success: function(data, script) {
        this.parent(data, script);
    }
});

Here is a quick example of how it can be used on a form. Note you need mootools-more with JSONP for it to work.


Sep 15th 2009 × mootools colour picker: mooRainbow

I was browsing around the internet and came across Iconza by turbomilk. As it seemed rather nice and my Framework Detector Firefox add-on sniffed out mootools, I had a look at the source.

It uses what looks like a colour picker plugin for mootools called mooRainbow. Nice to have in your toolkit, you never know. Iconza’s png trickery is not too shabby either, nice site (as you’d expect from Turnomilk anyway).