Most read posts this month



Dec 9th 2008 × snippet time: mooRating, a star based ajax voting script


This is just a little snippet that can enable you to use star based rating on a page and interactively do something with the voting results. It is not a plug and play solution, you can attach whatever events you want to it and have complete control over the number of stars on show, the colour transitions and formatting.

window.addEvent("domready", function() {
    doRating(4.6, true, {
        targetObject: $("myrating"),
        clickEvent: function(ratingOptions) { // save the vote
            new Request({
                url: "ratinger.php",
                method: "get",
                onComplete: function() {
                    alert("saved via ajax!");
                }
            }).send("a=vote&ratingID="+ratingOptions.ratingID+"&rating="+ratingOptions.newRating);
        }
    });
}); // end domready

Here is an example use with defaults, start value of 4.5 and an empty layer called “myrating” to hold it all:

You can run more than one instance of a “ratinger” per page, naturally – but they do need distinct IDs in order to differentiate the click events when saving data via ajax. This time, something very, very different: a 6 star rating in the style of a retro hi-fi stereo output indicator (a new gif file for the background), with the start value of 3.6 (4 stars) and ‘tips’ enabled: here is myrating2:



The code behind the above vote instance (if you can’t be bothered to view the source):


doRating(3.6, true, {
    // use some default value you have read from the DB that represents your start / current rating
    targetObject: $("myrating2"),
    maxStars: 6,
    tipShown: true,
    background: '#010',
    colourBase: '#550000',
    colourTarget: '#00cc00',
    starWidth: 22,
    border: 0,
    tipPadding: 0,
    starSpacing: 1,
    starHeight: 10,
    imageURL: '/images/stereo.gif',
    clickEvent: function(ratingOptions) { // save the vote
        new Request({
            url: "ratinger.php",
            method: "get",
            onComplete: function() {
                alert("saved via ajax!");
            }
        }).send("a=vote&ratingID="+ratingOptions.ratingID+"&rating="+ratingOptions.newRating);
    }
});

How to use on your site
As usual, nothing you get from this site just works, it requires you to actually know what you are doing… Using this particular mootools vote snippet is very simple, however. First, download the mooRating javascript source and save it. Include on a page after your usual mootools init lines and within domready, you can instigate a ‘ratinger’ / ‘vote’ widget within any element as defined by your html / css. You will probably need to save the star.gif image I made or make your own with some transparency…

Here are the default options the mooRating function supports:


var doRating = function(rate, addevents, options) {
    // mootools star rating system by dimitar christoff
    // v2.1 for mootools 1.2.1
    // last modified: 09/12/2008 19:37:15

    // defaults
    var options = $merge({
        background: '#fff', // vote cell background
        colourBase: '#f4edaf', // start colour (left side)
        colourTarget: '#f9e526', // end colour (right side)
        maxStars: 10, // number of stars
        starWidth: 24, // box with
        starHeight: 22, // box height
        starSpacing: 0, // space between stars
        imageURL: "/images/star.gif", // url to box background image
        tipPadding: 8, // padding around the vote text
        tipSize: "12px", // size of text in tip
        tipShown: false, // toggle tips
        border: "1px solid #ffffff", // border around the "stars"
        clickEvent: $empty() // what to pass as a function on click
    }, options);
// .. and so on and so forth.

I hope it helps somebody to add easily votes or product ratings on their pages with plenty of control. NB: you need color.js compiled into your version of mootools or you need to take out the colour gradiency.


Oct 30th 2008 × slidingTips: a mootools apple-style tooltip effect

This is not working since blog upgrade, looking into it

Seems that Apple really inspire design… After having done largerBox: a mootools apple-style modal lightbox effect, I thought I’d also do some animated tooltip effects similar to the ones on their site. So, I finally got around to it and just drafted an element method for the fragged tooltips (called, slidingTips or slidingTips) into my dci_core.js collection.

Not much more to say, here it is in action:

You can interact with all form elements in this div to get a tooltip

show on focus / hide o n blur:

show on click / dispose after 5 seconds:

show on mouseover / hide on mouseout:

The code? First, the Element.implement bits, 2 functions:

Element.implement({
    slidingTip: function(what, options) {
        // apple style tooltip
        var _this = this, coords = _this.getCoordinates(), options = $merge({
            eventEnd: "mouseleave",
            eventEndTrigger: _this,     // parent element or self
            topOffset: 90,             // offset when in full view
            topStartOffset: 100,        // offset for animation start
            opacity: .8,                // target opacity in full view
            className: "tooltip",       // linked to css
            morphOptions: {
                duration: 300,
                transition: Fx.Transitions.Sine.easeOut,
            },
            delay: 0,                    // can dispose on a timer, in seconds
            id: "tid" + $random(100, 1000)
        }, options);

        // we only need one tip instance per parent element.
        if ($type(this.tip) != "element") {
            this.tip = new Element("div", {
                "class": options.className,
                id: options.id,
            });
        }

        // if it's an existing one, with an implicit id, pick it up
        if ($(options.id))
            this.tip = $(options.id);

        // set initial options and html
        this.tip.set({
            opacity: 0,
            html: "<div style='padding:20px'>" + what + "</div>",
            styles: {
                left: coords.left + coords.width / 2
            }
        }).inject(document.body).removeEvents();

        // show it. cancel any previous animation instances for tip
        if ($type(this.morph) == "object")
           this.morph.cancel();
        else
            this.morph = new Fx.Morph(this.tip, options.morphOptions);

        // show it. really.
        this.morph.start({
            opacity: options.opacity,
            top: [coords.top - _this.tip.getSize().y - options.topStartOffset, coords.top - options.topOffset]
        }).chain(function() {
            // once done, decide how to exit
            if (options.delay == 0) {
                // based on an event.
                options.eventEndTrigger.addEvent(options.eventEnd, function() {
                    _this.morph.cancel();
                    _this.slidingTipaway();
                });
            }
            else {
                // based on a timed delay
                (function() {
                    _this.slidingTipaway();
                }).delay(options.delay);
            }
        });

        // define the tooltip close animation morph object
        var closeAnimation = {
            opacity: 0,
            top: coords.top - _this.tip.getSize().y - options.topStartOffset
        }

        // ... and save it within the parent element
        this.store("closeAnimation", closeAnimation);

        return this;
    },
    slidingTipaway: function() {
        // animate an slidingTip, opposite on in method.
        if (this.tip) {
            this.morph.start(this.retrieve("closeAnimation"));
        }

        return this;
    }
});

There is some CSS to this:

<
div.tooltip {
    background:transparent url(/images/tooltip-ie.gif) no-repeat scroll 50% 50%;
    height:90px;
    left:50%;
    margin-left:-151px;
    position:absolute;
    text-align:center;
    top:0;
    width:299px;
    z-index:1010000000;
    color: #327bb2;
    font-weight: bold;
}

And finally, the demo code:

window.addEvent("domready", function() {
    $("demofocus").addEvent("focus", function() {
        this.slidingTip("Please enter your first name and your surname", {
            eventEnd: "blur", // on blur, remove tip
            topOffset: 82 // tuck in more (heigh is 90 usually)
        });
    });

    $("demosubmit").addEvent("click", function(e) {
        e.preventDefault(); // stop submit from happening
        this.slidingTip("Sorry, you are required to complete all fields before you can submit", {
            delay: 5 * 1000, // remove tooltip after 5 seconds
            topOffset: 82
        });
    });

    // find all .demo_mouse class elements and tooltip them to show data-tip values
    $$(".demo_mouse").each(function(el, i) {
        el.addEvents({
            mouseenter: function() {
                this.slidingTip(this.get("data-tip"), {
                    id: "demoid"+i, // can assign implicit ids to shadows for scripting
                    morphOptions: {
                        duration: 600
                    }
                });
            },
            click: function(e) {
                // prevent the submit from working....
                e.preventDefault();
            }
        });
    });

});

Now, the fragged apple slidingTips currently uses this image:

tooltip ie friendly

This is a .GIF so it will be IE friendly (as opposed to a .PNG with transparency). Alpha blending/anti aliasing is not perfect but will work on a light background (hence the white around the demo code).

This one:

tooltip ie friendly

... way nicer. But, on IE7 even (which allegedly supports transparency in PNG), there is a nasty bug and alpha bleeding near the pointy arrow. You can try using it by changing the .tooltip css class.


Oct 17th 2008 × The simple MODAL window via mootools

Having noticed a trend on Google Webmaster Tools and even Google Analytics for a fair amount of searches and results on the subject of ‘modal’, here is a little snippet to help.

There is only so much you can do to customise a simple layer that takes up the whole visible screen – z-index, colour and opacity. Another thing that can be useful is to pass on click events at creation. But you can build on it all of this as you see fit, here is the code itself:

var toggleModal = function(backgroundColour, options) {
    // modal view for the whole screen
    // ver 2.02 17/10/2008 03:42:06
    if ($("modal")) {
        $("modal").dispose();
        return false;
    }

    var options = $merge({
        zIndex: 10000000,
        opacity: .8,
        events: $empty()
    }, options);

    if (!$type(backgroundColour) && !$("modal"))
        return false;

    return new Element("div", {
        id: "modal",
        styles: {
            position: "absolute",
            top: 0,
            left: 0,
            width: window.getScrollWidth(),
            height: window.getScrollHeight(),
            background: backgroundColour,
            "z-index": options.zIndex
        },
        opacity: options.opacity,
        events: options.events
    }).inject(document.body);
} // end toggleModal

// example usage
toggleModal("#fff"); // create a white modal, default options.
// ... do stuff
toggleModal(); // close it.

// something more fancy...
toggleModal("#555", {
    zIndex: 1000,
    events: {
        click: function() {
            $("modal").fade(0); // want to gently fade it out
            // do other stuff/cleanup here
            (function() { toggleModal(); }).delay(500); // removes the layer itself after fade done
        }
    }
});

// the function also returns the object so you can tweak it from the outside:
toggleModal("#fff").adopt(new Element("div", {"class": "intro", text: "Hi from modal land!"}).addClass("modals");

I hope somebody finds this useful. Please be aware that IE applies transparency using a filter:opacity but has been known to have issues allocating memory for the filter. As a result if you modal a very long page (like this blog), transparency in IE7 may be lost. There’s another school of thought that goes, a modal should disallow scrolling and focus on the visible screen area only, which works around this issue. I will post an updated / alternative function as soon as I can.


Sep 17th 2008 × largerBox: a mootools apple-style modal lightbox effect

I saw the animation apple do when viewing a trailer (non-HD) on their modal box and decided to replicate the effect for my image viewing in mootools.

Examples of largerBox v3.0 (animations / morphs / tweens don’t work too nice over iframes, mind)


UPDATE – 24/11/2009 largerBox is in the process of being refactored. largerBox v3 – beta 1 is available to look at and play with. It features a totally drag and drop solution – CSS is built into the javascript class, so are the images for next/previous and close. That’s right, there are no files to edit, updated, upload — aside from your images. Check the new source here: /js/largerBox.js

How does it work?
In the normal way, it takes a <a href=’imagename.jpg’> … </a> and attaches itself to the click event, not interfering in any way with your html. All you need to do is add ‘class=”fullimage”‘ to the anchor tag and fraggedBox will do the rest.

What do I need to get this to work?
You need to grab a copy of mootools 1.2.x – core.

You then need to grab the latest beta. Just look at the demo page anyway…