Skip to Content

In the blog Creating Functions Available to All UI5 controls in a single go !Sakthivel Elango showed us one way to extend a control to use third party functionality, there are many ways you could achieve this, similar to what the blog shows you can use a mixin pattern or a simple decorator pattern with jQuery extend or even write the logic directly into a controller. In this blog I will contrast those methods and show you how I like to do it using a delegate handler which listens on controls events, allowing you to attach the logic for example after a control has been rendered.

All controls inherit properties from sap.ui.core.Control which in turn inherits from sap.ui.core.Element, sap.ui.core.Element has an undocumented method addDelegates, not sure why it isn’t in the documentation but it is mentioned in the following method sap.ui.core.Element.html addEventDelegate and the method is used a lot in control development for adding additional functionality to controls.

An examples of where its used is in sap.ui.core.Control for triggering the busyIndicator after the control has been rendered “onAfterRendering”.

A good use case for a delegate is sap.ui.core.delegate.ScrollEnablement which is attached to controls which require scrolling capabilities, it is used to listen on events like onBeforeRendering, onAfterRendering, onfocusin,ontouchstart, ontouchmove, ontouchend, onBeforeScrollStart,onScrollEnd etc and then implement functionality for handling these events from either of the following third party libraries Zynga Scroller and iScroll

Below is the code necessary for extending a control to support jQueryUI draggable, it loads the third party dependencies and onAfterRendering calls the draggable() method to attach the functionality to the controls DOM reference wrapped in a jQuery object $()


(function () {
    "use strict";
    /*global jQuery, sap, my*/
    jQuery.sap.require('sap.ui.thirdparty.jqueryui.jquery-ui-core');    //dependencies
    jQuery.sap.require('sap.ui.thirdparty.jqueryui.jquery-ui-widget');
    jQuery.sap.require('sap.ui.thirdparty.jqueryui.jquery-ui-mouse');
    jQuery.sap.require('sap.ui.thirdparty.jqueryui.jquery-ui-draggable');
    jQuery.sap.require('sap.ui.thirdparty.jqueryui.jquery-ui-sortable');
    jQuery.sap.declare('my.draggableDelegate');
    my.draggableDelegate = function (oControl) { //inject control
        this.oControl = oControl;
    };
    my.DraggableDelegate.prototype = {
        onAfterRendering: function () {  //After the control has been rendered apply your logic
            this.oControl.$().draggable({
                cancel: false
            });
        }
    };
}());



Then to implement the delegate on a control


var oButton1 = new sap.m.Button({
  text: "Drag Me"
});
oButton1.addDelegate(new my.DragableDelegate(oButton1));



however instead of applying directly to a delivered control, it probably best to encapsulate the implementation in your own notepad control


(function () {
    "use strict";
    /*global jQuery, sap, my*/
    jQuery.sap.require('sap.m.Button');
    jQuery.sap.require('my.DraggableDelegate');
    jQuery.sap.declare('my.Button');
    sap.m.Button.extend("my.Button", {
        renderer: {},
        init: function () {
            sap.m.Button.prototype.init.apply(this, arguments);
            this.oDraggable = new my.DraggableDelegate(this); //create delegate
            this.addDelegate(this.oDraggable); //attach delegate
        }
    });
}());


to call your new button


var oButton1 = new my.Button({
  text: "Drag Me"
});


It may seem like a bit of an overhead, the advantage is you haven’t changed standard code and the feature can be easily found, reused, tested, enhanced and changed without worrying about leaked side effects or problems when upgrading.

here is a JSBin working example – UI5:Using a delegate to implement jQueryUI draggable

To report this post you need to login first.

3 Comments

You must be Logged on to comment or reply to a post.

  1. Jason Scott

    This is great John, I’ve wondered about the usefulness of delegates and when to use them. This is a great use-case.

    In your jsbin code I don’t think the line: “oButton1.addDelegate(new my.DraggableDelegate(oButton1));” is necessary. It works just fine without it…. The addDelegate is being handled inside my.Button class instead.

    When would you say is the ideal circumstances to use this technique? Possibly when you want to make minor enhancements to a standard control… When larger enhancements are required then maybe you use the renderer on a notepad control…

    (0) 
    1. John Patterson Post author

      wrt JSBin – thanks, i changed the code after i published thinking it would create a new milestone, it didn’t, have linked to new edit 

      When would you say is the ideal circumstances to use this technique?

      I think your suggestion is right, small changes apply directly to standard control, bigger enhancement create a notepad control.

      One of the nice things about delegates that i didn’t cover, is you can have multiple delegates and they can be configured to be called before or after the standard event handlers, I think this makes for really flexible composition of objects.

      (0) 

Leave a Reply