this.$owner is null or not an object -- Help!?

I'm trying to create a button control but I get an error (this.$owner is null or not an object) when the bolded code is executed. Can someone please help explain what I'm not doing right?


Active.Templates.Button = Active.System.Control.subclass();

Active.Templates.Button.create = function() {

    var obj = this.prototype;

    obj.setClass("control", "button");

    // define panel data model
    obj.defineButtonProperty("id",       "");
    obj.defineButtonProperty("label",    "");
    obj.defineButtonProperty("tooltip",  "");
    obj.defineButtonProperty("disabled", false);
    obj.defineButtonProperty("action",   function() { } );

    obj.setAttribute("type",     "button");
    [b]obj.setAttribute("value",    function() { return this.getButtonProperty("label") } );
    obj.setAttribute("title",    function() { return this.getButtonProperty("tooltip") } );
    obj.setAttribute("disabled", function() { return this.getButtonProperty("disabled") } );[/b]

    // attach the click event function
    obj.setEvent("onclick", function() { return this.getButtonProperty("action") } );

    // mouse over effects
    obj.setEvent("onmouseover", "mouseover(this, 'active-control-highlight')");
    obj.setEvent("onmouseout",  "mouseout(this,  'active-control-highlight')");

Steve N
June 21,

I don't have an error if I just include your code to the page. The following also works fine:

var obj = new Active.Templates.Button;
obj.setButtonLabel("Button 1");

I am only confused why did you put it into Templates 'namespace'?

Template is HTML fragment which does not contain its own data and is not painted by itself. Typically you use templates as part of control and template is requesting data from the parent control data model.

In which context do you have this error?

Alex (ActiveWidgets)
June 21,
Yes... you are right... the declaration should be:

Active.Controls.Button = Active.System.Control.subclass();
Active.Controls.Button.create = function() {

The error occurs in \lib\system\source.js:

_super[getProperty] = function(property, a, b, c){
    if (this[external]) {return this[external].getProperty(property, a, b, c)}
    return this.$owner[getProperty](property, a, b, c);
Steve N
June 21,

this type of composition is not implemented in the framework (yet). I guess you are building a control that contains other controls. What exists curently is:

1). static content
- setContent/getContent methods
- composite HTML is pre-built/cached
- function calls executed as methods of $owner (i.e. top level object == control or template)

2). templates
- define/set/getTemplate
- re-use/repeate the same template with different data items (lists/tables)
- data requests bubble up until top level object (control)

I think you should start by looking at simple list template but instead of repeating the same item template - concatenate your child controls for the output (you have to arrange storage yourself - setContent method will not work here).
Alex (ActiveWidgets)
June 21,
Thanks Alex,

OK, I think I understand it better now. You are quite correct assuming that I have nested controls. I didn't realize that methods and data requests are executed at the top-level object. This is where it's failing.

Are you saying that a future release of the framework will allow nested controls to exist and run within their own 'space' and use their own data model?

I shall have to rethink my design strategy.
Steve N
June 21,
What will work for sure is using controls in place of templates but I guess this may work in a current version as well (but not as 'static' content). I am not planning to have control containers (form, group etc.) yet. Maybe version 3 :-)
Alex (ActiveWidgets)
June 21,
Can you please give a small code example (pseudo code is fine) of how this might look? I'm still a bit unclear...
Steve N
June 21,

This topic is archived.

See also:

Back to support forum