Archive for the ‘Javascript’ Category

SleepyCod
by SleepyCod

Even more Drag&Drop coolness between your desktop and your browser!

Posted in DD, Javascript, Swell

We are making more & more progress with the native DnD API, and being native means fully taking advantage of Event Bubbling.

In essence this means that if you want to make for example a datatable with a lot of rows without attaching events to them (remember the flyweight pattern?) you’ll only need to set your draggable element at a higher level in the hierarchy to get the DnD behavior applied on all children nodes (marked with the draggable attribute), that’s powerful and of course, reduces a lot the memory footprint of your web application.

A lot of components could benefit of this approach, Treeview, Datatable, Listview and so on.

Another part of the example shows another level of interaction between the browser and desktop, and we are sure this one will get a lot of attention and excitement!

Swell drag&drop in actionAnd the code :)

var proxyElement = html.div(null, html.span({
    'cls' : 'dd-proxy-icon'
}), html.span('Moo'));
 
 
var draggableRows = new Swell.Lib.DD.Draggable('bleh', {
    'delegate' : true,
    'proxy'  : true,
    'proxyOverride'    : proxyElement,  
    'dataCallback' : function(dt) {
        var _currentEl = this.getDragEl().current(), _stdOut = [];
 
        for(var _n = 0, _l = _currentEl.childNodes.length; _n < _l; _n++) {
            if(_currentEl.childNodes[_n].nodeType === 1) {
                var _text = $(_currentEl.childNodes[_n]).text();
                _stdOut.push(Swell.Core.trim(_text));
            }
        }
        this.setData(dt, 'text/plain', _stdOut.join("\t"));
    }
});
 
var dropTarget = new Swell.Lib.DD.Droppable('moo');
 
dropTarget.ondrop = function(e, draggable) {
    if(!!draggable) {
        draggable.getDragEl().appendTo($('moo').current().tBodies[0]);
    }
}
Butterfish
by Butterfish

Drag and drop files from your desktop to your browser

Posted in Javascript, Swell

Since the last post, we’ve received a huge number of requests and questions about drag&dropping files onto your beloved browser.

The mechanism behind is quite simple:  the Ajax library, the DOM element wrapper and the Asset component are assuring most of the work (handling the upload and the callback process), the DDM detects the dragged files,  then your browser is doing the rest, defining the interaction between your desktop and the file input (nicely styled of course).

By now, two browsers are playing well with the demo (Safari 4, Chrome 2+)  while others degrades gracefully.

Here’s the code :

Swell.Core.Event.add('upload', 'change', function() {
    $('loader').show();
    $('foorm').xhr(function() {
        var currentEl = $('upload').current();
        $('filelist').show();
        for (var i = 0, len = currentEl.files.length; i &lt; len; i++) {
            $('filelist').appendHTML(currentEl.files.item(i).fileName + '
');
        }
        var imgs = this.responseText.split('|');
        new Swell.Core.Asset().load('img', imgs, function(img) {
            $('loader').hide();
            $(img).appendTo('image-container');
        });
    });
});

The demo:

ddimagesAnd the video:

Butterfish
by Butterfish

Swell Widget example: ImageZoom

Posted in Javascript, Swell

As Beta release is around the corner, we are glad today to provide the first swell widget. This widgets makes intensive use of Core components and shows how much power you have at your fingertips…

This is a widget that ecommerce companies often look for, which enables to zoom on an image and view much more details than on a thumbnail, without having to display the entire image; providing better user experience.

imagezoom

SleepyCod
by SleepyCod

Trigger image loading with Javascript and Swell

Posted in Javascript, Swell

As we are seeing growing interest for Swell, we now want to show how to use it and how cool it is :D , this is according to the milestones on our Trac a necessity and this will as well open up the project to a larger public.

One of the Core component (Lazy loader) plays well with another (Element) in this example.

playground

Enjoy!

SleepyCod
by SleepyCod

Dazzling performance with JSONP and Swell

Posted in Javascript, Swell

For an upcoming work we figured it would be useful to add JSONP support in our Asset component in order to load the given URL and once loaded, passback the JSON to a handler with the content.

What’s interesting with this approach is that we don’t rely on any hack to get the response such as evaluating all the script files in head or loading the content asynchronously then appending it.

There are numerous advantages using our solution :

  • You can load the JSON from multiple sources but keep a single handler, each JSONP file processed will be passed back as an argument
  • You can have a single handler for the whole sequence or listen events of each JSONP file being loaded with CustomEvents
  • The tags are removed from the DOM once loaded, this avoid memleaks or JSONP collision
  • This approach is robust and works equally between browsers even on old ones like MSIE 5.5

here’s a little example of what can be done:

Swell.Core.Asset.load('jsonp', [
    'http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=rideback&output=json&callback=',
    'http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=saintseiya&output=json&callback='
], function() {
    for(var _n = 0; _n < arguments.length; _n++) {
        var yim = arguments[_n];
        for(var _i = 0, _im; _im = yim.ResultSet.Result[_i++];) {
            html.img({
                'src'   : _im.Thumbnail.Url,
                'alt'   : _im.Title,
                'title' : _im.Title,
                'width' : _im.Thumbnail.Width,
                'height': _im.Thumbnail.Height
            }).appendTo('receiver');
        }
    }
});
SleepyCod
by SleepyCod

Introducing Swell’s lazy loader utility

Posted in Javascript, Swell

As we are preparing the upcoming release of Swell, we are actively working on a true and efficient dependency management system, and one of the key feature of the dependency manager is the ability to grab resources once the page is loaded.

Swell’s Core should be the only resource you would ever need to get started,  it is not an understatement to say that we’ll lose adopters if the system is too hard to build.
Every component should be able to load its own UI definition, I mean being able to lazy load any css or  image resource it needs.

Separation of concerns will help us to build a better library,  that’s the way it should be, that’s the way we are !

We have looked at the various javascript lazyloading implementations on the web, some are interesting and well-minded, some others are just bloated.

Keep it simple stupid!

Our lazy loading implementation is able to load and monitor script, css and image resources,  for example you want to use the Element component in your page and then want to use it when available into the global scope.

/** For a single script file without callback */
Swell.Core.Asset.load('script', 'Core/Element.js');
 
/** For multiple script files with a callback when all resources are loaded */
Swell.Core.Asset.load('script', ['Core/Element.js', 'Core/Hashtable.js'], function() {
    $('foo').addClass('meh');
});
 
/** Custom event when a single file is loaded */
Swell.Core.Asset.onResourceLoaded.subscribe(function(type, res) {
    if(type === 'img') {
        // Do something
    }
});
 
/** Advanced example */
var _imgs = $(document.body).getByClassName('swell-image-asset', 'img').setAttribute({'src' : 'blank.png'})
    .addEvent('mouseover', function() {
 
        this.addClass('loading');
 
        Swell.Core.Asset.load('img', 'largeimage.jpg', function(collection) {
            for(var _i = 0; _i &lt; collection.length; _i++) {
                this.setAttribute({'src' : collection[_i].src});
                collection[_i] = null;
            }
        }, this);
    }
);

Have fun !

Butterfish
by Butterfish

Ajax: Form Serialization

Posted in Javascript, Swell

When using Ajax to submit a form, you’ll have to attach as args the input fields name/value combination; this task can be very boring, especially if your form takes three pages…
This is where the form serialization feature strikes, by simply specifying the form(s) name to your XHR handle, the serializer will parse through your form and assemble each content input field into an object that’ll be passed automatically to your request.

We made a choice that come very handy in our case, every serialized form is returned in a global object and once requested, “stringified”.
Why using JSON?
In some case, let’s say… in “multiples select”, we can come up with multiple values, and when using GET you’ll definitely do something like key=val, with multiple values, key[]=val, but how much server-side languages can handle this kind of GET property? not much… whereas much languages are now able to unserialize JSON.

PHP is able to “decipher” passed arrays in GET, but what about the others languages? If there’s Java/Ruby/ASP.NET folks out there, we would like to hear from you!

XHR in Element

In order to save both time and lines, it was quite interesting to think of a way to implement XHR in our Element class, take a look at these working drafts:

// well, let's say we have two forms
var forms = $('foo','bar');
 
// will send them separately asychronously
forms.xhr();
 
// this time we want to harmonize their form[method] value
forms.xhr('POST');
 
// or their form[action] value
forms.xhr(null, 'foo.php');
 
// two concurrent ajax request is somehow too much, we'd better merge them!
forms.xhr('POST', 'foo.php', true);
SleepyCod
by SleepyCod

Cross browser key event handling with Javascript and Swell

Posted in Event, Javascript, Swell

Handling keyboard events with Javascript is an extremely difficult task considering each browser discrepancies.

One guy compiled all the differences into a single page that he adequately called “Javascript madness :  Keyboard events“, and from there you can clearly see the real madness :D

Of course we have directly experienced the aforementioned problems and found out pretty smart solutions for almost any browser.

The two major headaches were IE not firing keypress event on specific keys and Opera not able to prevent default behavior of keydown event.

HTMLEvents magic or how to fix messy browser implementation

The special keys encompass all the keys that don’t cause a character to appear, but execute a certain function.  Among these keys we can find shift, escape, pageDown, enter and so on.

Some general caveats (courtesy of quirksmode) :

  • IE doesn’t fire the keypress event for delete, end, enter, escape, function keys, home, insert, pageUp/Down and tab.
  • Onkeypress, Safari gives weird keyCode values in the 63200 range for delete, end, function keys, home and pageUp.Down. The onkeydown and -up values are normal.
  • Alt, Cmd, Ctrl and Shift cannot be detected on Mac, except in Opera. However, you can always use the altKey, ctrlKey, and shiftKey properties.

For getting rid of this weird behavior we are capturing special keys on keydown and use a static property to hold the keyname (keymapper) and keycode that we use when keypress event is fired.

As we didn’t want to hack our code too much we just simulate the keypress event on IE when the unsupported special keys are pressed.

// Check if keypressed is a special key
_specialKeyName = this.getSpecialKeyName(e.getKeyCode());
if(_specialKeyName) {
    this._specialKey = _specialKeyName;
    this._keyCode    =  e.getKeyCode();
    // This is a special key, we know that IE will not fire
    // keypress event, we'll do it for him :D
    if(Swell.Core.Browser.isIE) {
        this.simulate(o, 'keypress');
    }
}
 
/**
 * Fires programmatically a native DOM event
 * @function simulate
 *
 * @param {String|HTMLElement|Array} o the object to assign the handler to
 * @param {String} type event type : click, change, keypress, etc, never prepend "on" keyword as Swell does this job for you
 *
 * @see https://developer.mozilla.org/en/DOM/element.dispatchEvent
 * @see http://msdn.microsoft.com/en-us/library/ms536390(VS.85).aspx
*/
simulate : function(o, e) {
    var _event;
    // Testing if o is an object or a string
    // add is just dealing with DOM events, and is not meant to
    // handle custom events of Swell Objects
    // as Swell.Core.Dom is not part of the core distribution &lt;~20K :D
    // We will use the good old document.getElementById for element retrieval
 
    if(Swell.Core.isString(o)) {
        o = _getById(o);
    } else if(Swell.Core.isArray(o)) {
        // Loop on function
        for(var n = 0; n &lt; o.length; n++) {
            this.simulate(o[n], e);
        }
        o = null;
    }
 
    if(!o) {
        return;
    }
    if(document.createEventObject) { // IE
        _event = document.createEventObject();
        return o.fireEvent('on' + e, _event);
    }
    else {
        // All other browsers
        _event = document.createEvent('HTMLEvents');
        _event.initEvent(e, true, true); //event type,bubbling,cancellable
        return !o.dispatchEvent(_event);
    }
},
SleepyCod
by SleepyCod

Restrict field input with Javascript and Swell

Posted in Javascript, Swell

Today, we are delivering the first page to play around with Swell and we are quite happy of the result. We wanted to show how easy it is to restrict the characters typed in form fields.

By using the universal selector (*) built-in Swell’s Event library, you can catch any keystroke and of course retrieve its text representation  in your event handler !

Be careful the code behind the Event library is still in early Alpha stage and far from being production ready, have fun !

Restrict input chars playground page

SleepyCod
by SleepyCod

Painless publish/subscribe system with swell’s custom events

Posted in Javascript, Swell

Let me start with wikipedia’s own publish/subscribe pattern definition : Publish/subscribe (or pub/sub) is an asynchronous messaging paradigm where senders (publishers) of messages are not programmed to send their messages to specific receivers (subscribers). This decoupling of publishers and subscribers can allow for greater scalability… We absolutely wanted to have this pattern implemented into Swell as we are fervent supporters of the SoC. The goal was to be able to hook the Custom event model to potentially any class as well as using custom events outside of a class context.

Custom event model

By inheriting the CustomEventModel class built-into swell, the children class is augmented with new methods and collections brought from the model. Example :

    Swell.Core.Class({
        name        : 'Hashtable',
        namespace   : 'Swell.Core',
        inherits    : [Swell.Core.Enumerable, Swell.Core.CustomEventModel],
        ...

Swell.Core.Hashtable class now have those methods :

  • createEvent (creates a custom event that is bound to the class ex : onHashUpdated)
  • fireEvent (fires desired event and will notice all the subscribers aka execute callback functions)
  • subscribe (subscribe to a custom event of the class from/outside the class)
  • unsubscribe
  • getEvents

In the hashtable code, we use custom events to update a static property containing the length.

var _initEvents = function() {
    /**
      * Initialization of the event
      * @event onChange fires when an item is added/updated in the hashtable
    */
    this.createEvent('onHashUpdated');
    this.subscribe('onHashUpdated', _updateLength); //_updateLength is a private function of the class
}
...
/**
 * Now triggering the event
*/
set : function(key, value) {
    if(arguments.length === 1) {
        _hash[Swell.uniqueId()] = key;
    } else {
        _hash[key] = value;
    }
    this.fireEvent('onHashUpdated', this);
    return this;
},
...

Standalone custom events

This is the simplest way of using the custom event system.
In the example below we have created a basic object called button that makes use of custom events.

var button = function() {
    var value = 1;
 
    this.setValue = function(val) {
        value = val;
        this.onValueChange.fire();
    };
 
    this.onValueChange = new Swell.Core.CustomEvent('onValueChange');
}
 
var handler = function() {
    alert('button value has changed');
}
 
var btn = new button();
btn.onValueChange.subscribe(handler);
btn.setValue('toto');

And the firebug DOM :

Firebug DOM

Firebug DOM