Developer Tip of the Month: kontext-sensitives Hilfesystem in einer ExtJS Anwendung

In diesem Beitrag möchten wir eine recht einfache Möglichkeit vorstellen, wie eine kontext-sensitive Hilfe in einer ExtJS Anwendung realisiert werden kann. Dabei ist das Ziel, dass dem User beim Betätigen der F1-Taste Informationen zu derjenigen Komponente bereitgestellt werden, auf der sich der Mauszeiger gerade befindet.

Wir definieren einen ContextHelp-Controller, in dessen init-Methode ein Eventlistener registriert wird, der die Funktionalität ansteuert:

 

xt.define('MyApp.controller.ContextHelp', {
    extend: 'Ext.app.Controller',

    [...]

    init: function() {
        var me = this;

        [...]

        // triggered by event handler in ViewController when user hits F1
        me.on('showhelp', me.showHelp);
    },

    [...]

    showHelp: function() {
        var me = this,
            foundCmp,
            cmp = me.getActiveComponent(),
            helpRef;

        if (cmp) {
            if (cmp.helpRef) {
                alert('Help requested for: ' + cmp.helpRef);
            } else {
                foundCmp =  me.iterateCmpStructure(cmp);
                if(foundCmp !== null) {
                    alert('Bubble up: found helpRef: ' + foundCmp);
                } else {
                    alert('no helpRef found in component');
                }
            }
        }
    },

    /**
     * iterateCmpStructure
     * iterate up the component structure until a cmp with a helpRef was found
     * @param cmp
     * @returns {*}
     */
    iterateCmpStructure: function(cmp) {
        var me = this;
        if(!Ext.isDefined(cmp)){
            // could not find helpRef in CmpStruct
            return null;
        } else if ( cmp.helpRef ) {
            return cmp.helpRef;
        } else {
            return me.iterateCmpStructure(cmp.ownerCt);
        }
    }

    [...]
});

 

Zu beachten ist, dass die showHelp-Methode nach einer Property helpRef in der Komponetenstruktur nach oben sucht. Es muss also nicht jede Komponente über eine helpRef verfügen. So lassen sich beispielsweise viewspezifische Hilfetexte realisieren. Sobald eine helpRef refunden wurde, kann eine beliebige Aktion ausgeführt werden - im Beispiel einfach ein alert().

Unser Hilfesystem wird dann im ViewController der Viewport-Komponente in einem Listener auf den render-Event mit der F1-Taste verknüpft:

 

onViewportRendered: function(vp) {
    var me = this;

    // attach key event listener for help system
    Ext.getBody().on('keydown', function(e, target, options){
        if(e.getKey() === e.self.F1) {
            e.stopEvent();
            MyApp.app.getController('MyApp.controller.ContextHelp').fireEvent('showhelp');
        }
    });
}

 

Zu guter letzt müssen wir noch die helpRefs in den Komponenten festlegen:

 

tems: [{
    title: 'Center',
    region: 'center',
    helpRef: 'helpRef_center',
    layout: 'hbox',
    defaults: {
        xtype: 'panel',
        height: '100%',
        flex: 1,
        border: 1
    },
    items: [{
        html: 'foo'
    },{
        html: 'bar'
    }]
},{
    title: 'West',
    html: 'lorem ipsum',
    region: 'west',
    width: 200,
    helpRef: 'helpRef_west'
},{
    title: 'North',
    html: 'lorem ipsum',
    region: 'north',
    height: 100
}]

 

Das war's. Ein lauffähiges Beispiel findet Ihr als fiddle.