Make the Jo widgets âCoffeescript compliantâ
What is the problem ?
Unfortunately for me, Jo and Coffeescript does not share the same model of Class. I wish to do something like this (to add some behaviors to my joButton , for example)
class Button extends joButton
constructor:(args)->
super args
changeBackGroundColor:(color)->
@setStyle({background : color})
⊠But ⊠Coffeescript disagrees. Indeed, the Jo Class pattern is different from the Coffeescript model :
A âpureâ implementation of joButton in coffeescript would probably look like this (after JS comilation):
joButton = (function() {
function joButton(data, classname) {
joButton.__super__.constructor.call(this, args);
this.enabled = true;
if (classname) {
this.container.classname = classname;
}
}
joButton.prototype.createContainer = function() {};
//etc. ...
return joButton;
})();
and a âdaughterâ class of joButton :
Button = (function() {
__extends(Button, joButton);
function Button(args) {
Button.__super__.constructor.call(this, args);
}
Button.prototype.changeBackGroundColor = function(color) {
return this.setStyle({
background: color
});
};
return Button;
})();
But in reality :
joButton implementation :
joButton = function(data, classname) {
// call super
joControl.apply(this, arguments);
this.enabled = true;
if (classname)
this.container.className = classname;
};
joButton.extend(joControl, {
tagName: "jobutton",
createContainer: function() {
//...
},
//etc. ...
SubClass of joButton :
Button = function(args) {
joButton.apply(this, args);
}
Button.extend(joButton,{
changeBackGroundColor : function(color) {
return this.setStyle({background: color});
}
});
And it works fine, but my problem now, is that it is not really compatible with Coffeescript :( or Coffeescript isnât compatible with that ;)
- I donât think that @balmer (Dadâs Jo) is fun to rewrite Jo, even to please me.
- I did not want to rewrite my favorite framework (Iâm not even sure to happen)
But, I want âclassâ, âextendsâ, âCoffeScriptâ and âJoâ !!!
A Solution
I donât know if this is the best solution, but it works for me.
In the first place
- I create a âbase Widget Classâ that copies all members of a âJo Widgetâ
-
I add a property
isCoffeeWidget
setted totrue
(we will see later why)class Widget constructor:(args)-> for item of @joWidget @[item] = @joWidget[item] @isCoffeeWidget = true
-
Now we can write Classes that inherit
Widget
and that retrieve the properties and methods of Jo widgets :# fake joButton class JOButton extends Widget constructor:(args)-> @joWidget = new joButton args super args
# fake joInput class JOInput extends Widget constructor:(args)-> @joWidget = new joInput args super args
# and so on âŠ
In the second place
If you want to do something like that : myJoGroup.push myNewFakedButton
, it will not work.
Indeed, the joContainer.push()
method is waiting for an Object
or an Array
(of Objects
). So, we have to override joContainer.push()
method. Write this code (duplicate the code and patch it) :
joContainer.prototype.push = function(data) {
/* START --- working with Coffeescript ---*/
if (data.isCoffeeWidget) {
this.container.appendChild(data.container);
}
/* END --- working with Coffeescript ---*/
if (typeof data === 'object') {
if (data instanceof Array) {
// we have a list of stuff
for (var i = 0; i < data.length; i++)
this.push(data[i]);
}
else if (data instanceof joView && data.container !== this.container) {
// ok, we have a single widget here
this.container.appendChild(data.container);
}
else if (data instanceof HTMLElement) {
// DOM element attached directly
this.container.appendChild(data);
}
}
else if (typeof data === 'string') {
// shoving html directly in does work
var o = document.createElement("div");
o.innerHTML = data;
this.container.appendChild(o);
}
return this;
}
Remark : the only update/patch is :
/* START --- working with Coffeescript ---*/
if (data.isCoffeeWidget) {
this.container.appendChild(data.container);
}
/* END --- working with Coffeescript ---*/
And finally âŠ
You can do that :
class Button extends JOButton
constructor:(args)->
super args
changeBackGroundColor:(color)->
@setStyle({background : color})
myCuteButton = new Button "Hi! I'm a cute button"
anyJoContainer.push myCuteButton
# you can push Arrays of faked widgets
myCuteButton.changeBackGroundColor "red"
To conclude
- If you have a better idea, feel free to contact me
- You have no excuse not to do âJo + Coffeescriptâ
Have a nice day! @k33g_org
Tweet