MochiKit by Example

An overview of MochiKit with three real-life examples.
Example 1: MochiKit in a Simple Page

The MochiKit package is easy to install. If you downloaded the zip version, move the Mochikit folder in the lib folder to your Web space. To use the Subversion version, copy the Mochikit folder from your checkout.

Create the following HTML page:

<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xml:lang="en" lang="en">
<head>
    <meta http-equiv="Content-Type"
        content="text/html; charset=utf-8" />

    <title>MochiKit Example #1</title>
    <script type="text/javascript" charset="utf-8"
        src="Mochikit/MochiKit.js" />
    <script type="text/javascript" charset="utf-8"
        src="example1.js" />
</head>

<body>
        <p style="background: red;
            padding-top: 1em;">
        Hello world this is Mochikit!</p>
</body>
</html>

Notice the following line in your <head> section, which loads MochiKit:

<script type="text/javascript" charset="utf-8"
    src="Mochikit/MochiKit.js" />

Also notice that in the body is a paragraph with a red background. This box is plain-looking. Wouldn't it be great if it had rounded corners? MochiKit makes it easy.

First, we want to execute a JavaScript function when we load the page. The MochiKit function for that is MochiKit.DOM.addLoadEvent(). In JavaScript, the namespace specifiers are optional, but for clarity, we include them here.

We create a separate file for our JavaScript (a separate file is best). In the file, we have one function and a call to addLoadEvent():

function myLoadFunction()
{
    MochiKit.Visual.roundClass('p', null);
};

MochiKit.DOM.addLoadEvent(myLoadFunction);

MochiKit's roundClass allows you to specify an entire class type, and it rounds all of the elements of that class. You also can round elements selectively with MochiKit.Visual.roundElement(), which accepts either a string specifying the id or an element object.

Example 2: Turning Clicked Links into SPANs

Our second example uses MochiKit.Base.map(), MochiKit.Base.partial(), MochiKit.Signal and MochiKit.DOM to create a link that can be clicked only once and then goes away:

function myLoadFunction(eventObj)
{
    /*
        Find all A elements whose class is
        "onepush" and make them all to call
        handleJSHREFClick() in response to click
    */

    elementsToApplyOn =
        MochiKit.DOM.getElementsByTagAndClassName(
            "a", "onepush");

    /*now that we have all of the elements that
    match our transformation query run our function
    that connects everything, calling it once
    for every item.*/
    MochiKit.Base.map(
        connectOneClickOnly, elementsToApplyOn );
}

MochiKit.Signal.connect(window, "onload", myLoadFunction);
//end main and load

MochiKit's Signal module allows us to have functions called when events happen (it's based off Qt's signal/slot mechanism). In the case of the last line of code here, we are having the window object's onload event call our load function. Careful readers will remember MochiKit.DOM.addLoadEvent() used in the first example, and yes, we are using similar functionality with MochiKit.Signal. Be aware that once you choose one method of handling the load event, you cannot, in the same script, use the other method—they are incompatible in that way.

When the document loads in the browser, myLoadFunction() is called. This function gathers all the A elements whose class is oneclick and passes them, one by one, to the connectOneClickOnly function. The MochiKit.Base.map function could be seen as a convenience in writing the following pattern:

for (i = 0; i < elementsToApplyOn.length; i++)
   connectOneClickOnly(elementsToApplyOn[i]);

Next, we examine the real sweet spot for partial() and bind()—providing parameters to callback functions:

function connectOneClickOnly(linkElement)
{
    /*
        This function gets called for each A of
        type "oneclick" we have. Hook it up so
        that our handleJSHREFClick gets called
        (properly) when a user clicks the
        linkElement object
    */

    /*Each of our calls to handleJSHREFClick, in
    addition to getting the event object passed to
    it via MochiKit.Signal, also gets called with
    the object to call to create our replacement.
    */

    newH = partial(handleJSHREFClick, makeNewObj);

    MochiKit.Signal.connect( linkElement,
        'onclick', newH );
} //end connectOneClickOnly

Remember, MochiKit.Base.partial() and MochiKit.Base.bind() allow for runtime creation of functions that are based on other functions. These wrapper functions can provide parameters or even remap the JavaScript for this variable to the functions they are wrapping.

In this case, we use MochiKit.Base.partial(), because there is no way to provide arbitrary arguments to functions called via MochiKit.Signal (or any other MochiKit methods that call back to user functions). Using MochiKit.Base.partial(), we can pass as many parameters as we want, and MochiKit is none the wiser. In this case, we supply a function, which creates the replacement SPAN element, to our event handler callback. We have MochiKit.Signal call our function when the user clicks on our element:

function makeNewObj(target)
{
    /*
        Create a new item to replace our target
        with.
        Return the created element
    */

    makeNew = SPAN({});

    inHTMLStr = "One Click Only!";

    makeNew.innerHTML = inHTMLStr;

    return makeNew;
}

function handleJSHREFClick(makeNewF, eventObj)
{
    /*
        When one of our "oneclick" elements have
            been clicked, this function runs.
    */

    ourTarget = eventObj.target();

    /*stop the event right here (don't let it go to
    the href listed in the A)
    Here also so the event is stopped if we have
    errors further on*/

    eventObj.stop();

    //call our function that creates new elements
    makeNew = makeNewF(ourTarget);

    swapDOM(ourTarget, makeNew);
} //end click functionality code

The handleJSHREFClick() function is called, as previously mentioned, when a user clicks on our oneClick A elements. Normally, this function would accept only one parameter: the eventObj parameter passed by MochiKit.Signal. Because we used MochiKit.Base.partial(), the function is passed another parameter (in this case, the function to call to create our replacement object).

MochiKit.Signal takes care of the hard work of handling events. No matter what browser the user is using (or what event modal that browser uses), the JavaScript code doesn't have to change—the custom event object from MochiKit.Signal takes care of all that for you. Through the passed event object, you can get the key state, the mouse state, the object that triggered the event, the object connect()ed to the event, what type of event happened, and even stop the event from propagating further by preventing the default action of the DOM object.

handleJSHREFClick() swaps the item the user clicked on with the element we created. First it stops the event, because (in this instance) we don't want to go any further (that would follow the HREF element of the A, something we don't want to happen in this particular example).

The code that creates our replacement span is in the obvious place: makeNew = SPAN({}), yet this monster requires some explanation. DOM elements are created through MochiKit via functions in MochiKit.DOM. Like other MochiKit modules, there's a lot here. Functions to create, functions to query, swap and even convert DOM elements can be found in this module—getElement(), getElementsByTagAndClassName(), currentDocument(), currentWindow() and createDOM() to list a few. MochiKit.DOM.createDOM() is what is (indirectly) used here. MochiKit.DOM includes shortcuts to create common DOM elements (A, BUTTON, BR, CANVAS, DIV, FIELDSET, FORM, H1, H2, H3, HR, IMG, INPUT, LABEL, LEGEND, LI, OL, OPTGROUP, OPTION, P, PRE, SELECT, SPAN, STRONG, TABLE, TBODY, TD, TEXTAREA, TFOOT, TH, THEAD, TR, TT and UL, at the time of this writing). These are called with the attributes specified in the associative array parameter. In the passed array, each key corresponds to an attribute of the HTML element. For example, to create a link to example.com, the code would be:

makeNew = A({'href':'http://www.example.com'});

This example covered a lot of ground—MochiKit.Signal.connect(), MochiKit.Base.partial() and MochiKit.DOM.createElement(). However, we've scratched only the surface of these, and there's a whole lot more of MochiKit to cover. The next example takes the normal login box found all over the Web and “Web 2.0's” it up.

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Interactive Web pages

Anonymous's picture

Hi,
thanks for the informative article. chevy trucks

Thanks

Nice document

Jitesh's picture

A great informative stuff about Mochikit DnD.
Thanks for the tutorial.

Correction

jitesh's picture

Sorry mistakenly I have used the word DnD, just omit the word while reading.

Thanks
Jitesh

ucundan?

ucundan's picture

At the Voice On the Net (VON) conference in Toronto, Skype Technologies co-founder and CEO Niklas Zennstrom reported that a mobile version of Skype will be available this year.

helping

Wellnesshotel's picture

thanks for this helpfully article

Re.

zutestrane's picture

sounds like an new fancy name like mootools....

kredit

Anonymous's picture

Thanks for very interesting article. I really enjoyed reading all of your posts. It’s interesting to read ideas, and observations from someone else’s point of view… makes you think more. So please keep up the great work. Greetings

big thx

gregor's picture

Hi,
a big thanks for you - i like your article and will thank you for the examples and the code - I know it's a hard and long work to collect all the information to write such an article! Keep on your work - I will be back sonn and like to read another article written by you :)

Great job

NewSitesBlog's picture

I do congratulate you for the info. I found it to be very useful. Thank You

MochiKit

NBA's picture

Nice! You almost have me convinced. I'm going to put this page in my favorites to go over it better in the future. You covered a couple of things that I would like to be able to address in Javascript as instead of server side.

ask to you

youtube's picture

Why GPLv3 Will Supplant GPLv2

try and report

Chris's picture

Hi,
thanks for the informative article and the work with it! I will try it out and report my results soon.

Kindly regards,
Chris

Hi Should Mochikit.Visual

Balance's picture

Hi Should Mochikit.Visual Round work in all web elements like table, div, jne? I tried to use round in table, div and h1 and only h1 element worked. I used ie7 and firefox 2.0.0.4. Could someone show me a example how should I use this round function in div or other elements. Thanx allready.

looks sweet

Mac Millan's picture

dang it looks phenomenal. It is Java-based, though. IMO that's a good thing, but a lot of hosting services either don't support Java or charge more for Java support.

Thank you

güzel sözler's picture

Unfortunately, not everyone is such a big fan of Java - including myself.

Great post Ryan Wilcox.

JohnZ's picture

Great post Ryan Wilcox. However, I’m not sure I agree 100% about everything you’ve got here. I dont like JS.
Best Regards.

Slow movers are static and need to take classes...

protoman's picture

...prototypic (pronounce: 'Real') programmers are dynamic and never die.

js is....

cms's picture

Hey
I dont like JS...
I'm webmaster about 2 years...
and i use html, css, php, mysql, but sometimes JS is nessesery
at least its use full (if you can use it)

so, today i make my first own js script
and now collect js articles.. like this ;)

thx and greetings

MochiKit

ADAC's picture

Nice! You almost have me convinced. I'm going to put this page in my favorites to go over it better in the future. You covered a couple of things that I would like to be able to address in Javascript as instead of server side.

I'll be looking into this in detail in the near future!

Ajax seems to be the future

Free Software Downloads's picture

At this point, after Web 2.0 wave has pasted, I think the Ajax would be the way to come closer to what the people really want from the web.
MochiKit comes to increase the power of Ajax and offers to programmers a very powerful library. Very good article.

Would have been nice to have

Anonymous's picture

Would have been nice to have the html code for testing...

You should also check out

Anonymous's picture

You should also check out http://mochibot.com/, which is a nice flash content tracker made with monchikit. You'll see lots of sortable tables and XMLHttpRequests. The pages load extremely fast, and you can refresh the data without a full page reload.

Mochibot

MarcoR's picture

Mochibot is really one of the hottest thing i have seen in the last time, try it on your own... Cheers, Marco

SCRIPT tag syntax/usage problem

ch4dwick's picture

For some reason this doesn't work (in fact, it never worked for me in the first place):

<script type="text/javascript" charset="utf-8" src="Mochikit/MochiKit.js" />
<script type="text/javascript" charset="utf-8" src="example1.js" />

Better make it read:

<script type="text/javascript" charset="utf-8" src="Mochikit/MochiKit.js"></script>
<script type="text/javascript" charset="utf-8" src="example1.js"></script>

Best regards. :)

DTD error

Anonymous's picture

The syntax
<script type="text/javascript" charset="utf-8" src="example1.js" />
is allowed in xhtml but not in html

You´re right, but there

Maria's picture

You´re right, but there must be another problem with the syntax.

exactly.

directory's picture

exactly, but it doesn't make much difference. Does it?

One should tell users WHAT

Anonymous's picture

One should tell users WHAT BROWSER/VERSION this isn't working in as it works fine in Firefox.

ZK

ld's picture

Yet another web lib which did not understand Web 2.0...
I recommend everybody to try ZK, Ajax with no javascript (sourceforge project).

ZK apps runs a small JS engine on the browser which only reports browser events, and the web server updates the DOM via xmlrpc. This is Web 2.0 !

Mochikit has mojo

Anonymous's picture

Hmmm, I don't see why ld has to bash Mochikit. Mochikit seems like a very useful way to leverage javascript and web 2.0 is not a sharply defined term.

There was a piece about ZK in the latest Practical Webdesign. I still don't understand why you should use yet another scripting language (ZUML) and at first sight the fancy ZK components do not seem to be easy to customize.

I would vote for JSF, Tapestry or Wicket with a good AJAX framework as a java programmer.

alpella cikolata

alpella's picture

bu sitede alpella cikolatalari var dai

ZK

msn ifadeleri's picture

still don't understand why you should use yet another scripting language (ZUML) and at first sight the fancy ZK components do not seem to be easy to customize i am completely agree

Dear Mr Hammer, not everything is a nail

Xavier's picture

Yet another web lib which did not understand Web 2.0...

  • javascript framework != web lib. JavaScript is not limited to run within a browser, and to run against a web server, java or otherwise
  • javascript != Ajax != Web 2.0 Using "web 2.0" as a synonym of using xmlhttprequest+dhtml is either ill-informed or shameless jumping into the hype
  • promoting your tool != bashing other tools

ZK

Nicholas Petreley's picture

I just checked it out and it looks phenomenal. It is Java-based, though. IMO that's a good thing, but a lot of hosting services either don't support Java or charge more for Java support. Maybe that'll change once Java has been GPLed as far as Sun can take it. Maybe it's changing already and I'm just out of touch with what providers are offering. ;)

Regardless for all other needs (those other than using a hosting service), it looks fabulous.

What Java,

What Java's picture

What Java, Javascript/Mochikit isnt related to Java! btw, I can't get the rounded borders example to work. Mochikit is very well documented for n00bs. I don't understand the advanced library/packinging/classing syntaxes not covered in O'Reilly's Learning Javascript book.

One should tell users WHAT

Anonymous's picture

One should tell users WHAT BROWSER/VERSION this isn't working in as it works fine in Firefox

I meant to say, Mochikit _IS

What Java's picture

I meant to say, Mochikit _IS NOT_ well documented for n00bs, not the other way around. Typo.

Unfortunately, not everyone

ch4dwick's picture

Unfortunately, not everyone is such a big fan of Java - including myself.

I’ve tried your advices,

pilka's picture

I’ve tried your advices, but unfortunatly it doesn’t work. Don’t know maybe i’em doing something wrong. To tell the truth i’m a noob in java.