Creating a Custom Dojo Transport

Dojo has already built-in transport types like xmlhttptransport, iframetransport and etc but a custom dojo transport might be helpful if you need to do some extra stuff when using dojo.io.bind for making the ajax requests. One cool example for this use case is adding the jsf state at client side to the ajax request, this helps ajax components like inputsuggestajax work with client side state saving. Here is FacesTransport;

 dojo.provide(“extensions.FacesIO”);

dojo.io.FacesTransport = new function() {
    this.canHandle = function(kwArgs) {
        return this.isClientStateSaving() && dojo.io.XMLHTTPTransport.canHandle(kwArgs);
    }

    this.bind = function(request) {
        if (this.isClientStateSaving()) {
            request.method = “post”;
            this.addJsfState(request);
        }
        return dojo.io.XMLHTTPTransport.bind(request);
    }

    this.isClientStateSaving = function() {
        return dojo.byId(“javax.faces.ViewState”);
    }

    this.addJsfState = function(request) {
        request.content = request.content || {};
        this.addInputValue(request.content, “javax.faces.ViewState”);
    }

    this.addInputValue = function (content, inputName) {
        var control = dojo.byId(inputName);
        if (!control || !control.value)
            return;
        content[inputName] = control.value;
    }

    dojo.io.transports.addTransport(“FacesTransport”);
    dojo.io.transports.reverse();
}

A transport has two methods to implement which are canHandle and bind; canHandle defines if this tranport can be used for the asynchronous request and bind does the request itself. FacesTransport uses XMLHTTPTransport itself actually with a little bit of decorating(Changes request type to use “post” and adds jsf state hidden variable). Also a custom transport needs to add itself to the dojo.io.transports map which defines the rolled in transports.

After upgrading to dojo 0.4.x in myfaces, FacesTransport stopped working because although added, it was getting ignored. Turns out in 0.4.x a bug was fixed in which always the last transport added was always picked and after the fix the first available transport is used. That was the reason why FacesTransport gets ignored because there was already a tranport like XMLHTTPTransport loaded so it gets picked up before it’s FacesTransport’s turn. In order to overcome this, I’ve reversed the dojo.io.transports list after adding it to set FacesTransport as the first transport to be checked out in the available transports list, that way the issue is resolved.

One Response to Creating a Custom Dojo Transport

%d bloggers like this: