Troncador Troncador - 4 months ago 40
Javascript Question

JQuery UI inheritance polymorphism

Is there a way to have polymorphism in the inheritance of a widget in jQuery UI?

For example I want to do something like:

$.widget('tr.fatherClass', {
getValue: function() {
return null;
}
...
});
// sonClass1: extends from the father
$.widget('tr.sonClass1', $.tr.fatherClass, {
getValue: function() {
return this._fooFunction1();
}
...
});
// sonClass2: extends from the father
$.widget('tr.sonClass2', $.tr.fatherClass, {
getValue: function() {
return this._fooFunction2();//
}
...
});
// create an instance of a "sonClass"
$('#foo1').sonClass1(options);
$('#foo2').sonClass2(options);


Then I want to use the method "getValue" without knowing the name of the son class:

$('#foo1').fatherClass('getValue'); // run _fooFunction1() of sonClass1
$('#foo2').fatherClass('getValue'); // run _fooFunction2() of sonClass2


But this is not possible:

jquery.js:250 Uncaught Error: cannot call methods on variable prior to initialization; attempted to call method 'getValue'


In the forum of JQuery, Scott Gonzalez explains that "Creating a widget only creates one widget, not every widget in the prototype chain" link

There is any workaround or solution to do this in an elegant way?

Answer

You can save fatherClass as a data for element with some key like fatherObject it should go in father's _create() method...

$.widget('tr.fatherClass', {
  _create: function(){
    $(this.element).data( 'fatherObject', $.tr.fatherClass.prototype );
  },
  ...
};

And later retrieve values using...

$('#foo').data('fatherObject').getValue()

or

$('#bar').data('fatherObject').getValue()

$.widget('tr.fatherClass', {
  _create: function(){
    $(this.element).data( 'fatherObject', $.tr.fatherClass.prototype );
  },
  getValue: function() {
    return 'yellow'; // Father likes yellow
  }
});

// extends from the father
$.widget('tr.sonClass', $.tr.fatherClass, {
  getValue: function() {
    return 'blue'; // Son likes blue
  }
});

// extends from the father
$.widget('tr.daughterClass', $.tr.fatherClass, {
  getValue: function() {
    return 'pink'; // Daughter likes pink
  }
});

// This is son
$('#foo').sonClass();

// This is daughter
$('#bar').daughterClass();

// Son's fav color
console.log( $('#foo').sonClass('getValue') );

// Son's FATHER's fav color
console.log( $('#bar').data('fatherObject').getValue() );

// Daughter's fav color
console.log( $('#bar').daughterClass('getValue') );

// Daughter's FATHER's fav color
console.log( $('#bar').data('fatherObject').getValue() );
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<div id='foo'></div>
<div id='bar'></div>

Comments