Search code examples
javascripticefacesprototypejsicefaces-1.8

Extending methods in Javascript classes


I'm ("still", for those who read my previous posts) working on an ICEFaces web application.

This question can be interpreted as general Javascript question, so read on if you don't know much about ICEFaces

I need to extend the behaviour of the classes created by ICEFaces Javascript framework, in particular ToolTipPanelPopup.

I cannot modify the source code of the library (otherwise I would have achieved my goal). This is how ICEFaces defines the class (much like jQuery and other Javascript frameworks).

ToolTipPanelPopup = Class.create({
   [...]
  showPopup: function() {
    [...]
  },


  updateCordinate: function(event) {
     [...]
  },

    [...]
});

My question is very simple

How do I extend the behaviour of showPopup() function in order to run my custom function at the end of it?

I mean something like following Java example code that supposes inheritance

public void ShowPopup()
{
    super.ShowPopup();
    customMethod();
}

Solution

  • Something like this should work:

    var original = ToolTipPanel.showPopup;
    ToolTipPanel.showPopup = function() {
       original();  //this is kind of like the call to super.showPopup()
       //your code
    };
    

    I tried out this trivial example in Firebug, and it seems to work:

    var obj = {
       func: function() { 
         console.log("foo"); 
       }
    };
    
    obj.func();
    
    var original = obj.func;
    obj.func = function() {
       original();
       console.log("bar");
    };
    
    obj.func();
    

    Firebug output:

    foo
    foo
    bar
    

    So what's happening here is that you're saving a reference to the original showPopup function. Then you're creating a closure and assigning it back to showPopup. The original showPopup is not lost, because you still have a reference to it in original. In the closure, you call the function that original references, and then you have your own code. Just swap around the order if you want to do something first before you call original. Since you're using a closure, original is lexically bound to the current scope and should be available every time the new showPopup is called (if I'm wrong about this, someone please correct me).

    Let me know if this works out for you.