1

I am new to javascript so I am having some problem creating an object, then changing it properties afterwards through prototyping.

Here is the code I have:

function test() {
    this.xCssClass = "placeholder";
    this.init = function () {
        var btn = document.createElement("div");
        btn.className = this._CssClass;
        this.Node = btn;
    }
    this.Node;
    this.CreateInterface = function () {
        var btn = document.createElement("div");
        this.Node = btn;
    }
    this.init();
}
test.prototype.CssClass = {
    get CssClass() {
        return this._CssClass;
    },
    set CssClass(arg){
        this.xCssClass = arg;
        this.className = "args";
    }
}
var x = new test();
document.body.appendChild(x.Node);

x.xCssClass="GHR"
Debug.WriteLine(x.xCssClass);

When I try to redefine the cssclass it redefines but it doesnt update the object that was added to the Dom. I want to be able to go: x.xCssClass="some css class" and have the x object update in both javascript and the dom. Right now it is only updating in javascript. What I am doing wrong? Am I confusing the instances? Any help would be appreciated. Thanks

Greg H-R
  • 83
  • 7
  • 1
    In general, you shouldn't use `prototype` to add properties but only to add methods. In most cases properties should be defined inside the constructor. – basilikum May 05 '14 at 15:18

5 Answers5

0

Once it is append to DOM, you'll need to manually update it.

You can do the below:

function test() {
    this.xCssClass = function(class){
      this.Node.className += ' '+ class;
    };
    this.init = function () {
        var btn = document.createElement("div");
        btn.className = this._CssClass;
        this.Node = btn;
    }
    this.Node;
    this.CreateInterface = function () {
        var btn = document.createElement("div");
        this.Node = btn;
    }
    this.init();
}

Now, you can do this:

x.xCssClass("GHR");
Amit Joki
  • 58,320
  • 7
  • 77
  • 95
  • You example works very well than you. This bring up another question though. Why does this.xCssClass = function(class){ this.Node.className += ' '+ class; }; but the getter and setters dont work? test.prototype.CssClass = { get CssClass() { return this._CssClass; }, set CssClass(arg){ this.xCssClass = arg; this.className = "args"; } } – Greg H-R May 05 '14 at 15:27
  • @GregH-R, I am adding the class name to the `Node `by doing `+=` – Amit Joki May 05 '14 at 15:36
  • by doing += aren't you just appending to what is already there? That's basically just adding another css class right? Not replacing the current one. But the main wuestion is how to get it into the form x.cssClass to retrieve value and x.cssClass="class" to set new value. With your solution it is x.cssClass(arguement); instead of x.cssClass=arg – Greg H-R May 05 '14 at 15:41
0

When a property reference appears on the left side of an assignment (as an l-value), then the property update is always made directly to the object involved, and not its prototype. Whether there's a like-named property already on the prototype object doesn't matter.

Pointy
  • 405,095
  • 59
  • 585
  • 614
0

To update the Element you need to create a function like Test.prototype.setCssClass and in that function set the class of this.btn. what the value of this is is explained in the link at the end.

You can move all the functions to Test.prototype and should have a constructor function start with a capital (Test instead of test)

More on constructor functions and prototype here.Prototypical inheritance - writing up

Community
  • 1
  • 1
HMR
  • 37,593
  • 24
  • 91
  • 160
0

Lets take this line by line ...

// Okay cool a constructor function
function test() {
    // Setting your class
    this.xCssClass = "placeholder";
    // Hmmmm why do you have an init here ... okay sure w/e.
    this.init = function () {
        // create div element
        var btn = document.createElement("div");
        btn.className = this._CssClass;
        // Okay you set it as a property node.
        this.Node = btn;
    }
    this.Node;
    // Uh what's this for
    this.CreateInterface = function () {
        var btn = document.createElement("div");
        this.Node = btn;
    }
    // Ok
    this.init();
}
// Setting a property on a prototype! Okay.
test.prototype.CssClass = {
    // Wtf? This is weird.
    get CssClass() {
        return this._CssClass;
    },
    // Wtf? Also weird. 
    set CssClass(arg){
        this.xCssClass = arg;
        this.className = "args";
    }
}
var x = new test();
document.body.appendChild(x.Node);

// Uh xCssClass isn't even a property in x's prototype ...
x.xCssClass="GHR"
Debug.WriteLine(x.xCssClass);

I recommend reading about JavaScript prototypes. What I think you want is this:

test.prototype.getCssClass = function() {
  ...
};

test.prototype.setCssClass = function(arg){
  ...
};
linstantnoodles
  • 4,350
  • 1
  • 22
  • 24
  • The getters and setters are weird? – Greg H-R May 05 '14 at 15:30
  • 2 problems: you're not defining object properties correctly (so those setters and getters aren't even set in the first place I'm surprised if you don't get runtime errors). The other problem is that even if they were set correctly they'll never be found on the prototype chain. – linstantnoodles May 05 '14 at 15:34
  • Makes sense. But then how am I suppose to get it in the form of test.cssClass to retrieve the value of the objects cssClass and test.cssClass="newcssclass"; to set the value. The way you describe I would have to do x.getCssClass(); and x.setCssClass("newcssclass"); This is the reason I used the get and set. Which I seemed to have used incorrectly. – Greg H-R May 05 '14 at 15:37
0

I solved it by using Object.defineProperty prototype method. Below is a code snipped of a working button object. Thanks for all your help guys :)

function Button() {
    this.Node;
    this.Target;
    this._CssClass;
    this._ID = "";
    this._OnClick = "";
    this._Text = "";
    this._data = "";
    this._IsEnable =true;//Can be set to false
    this._Visible = true;//Can be set to false
    this._ToolTip = "";
    this.NodeCreate = function () {
        Debug.WriteLine("node created");
        var btn = document.createElement("div");
        this.Node = btn;
    }
    this.NodeCreate();
}
Object.defineProperty(Button.prototype,"CssClass",{//Sets and gets the css class
    get: function () {
        return this._CssClass;
    },
    set:function(args){
        Debug.WriteLine("set");
        this._CssClass = args;
        this.Node.className = args;
    }
});
Object.defineProperty(Button.prototype, "ToolTip", {//Sets and gets the ToolTip
    get: function () {
        return this._ToolTip;
    },
    set: function (args) {
        this._ToolTip = args;
        this.Node.title = args;
    }
});
Object.defineProperty(Button.prototype, "ID", {//Sets the css ID
    get: function () {
        return this._ID;
    },
    set: function (args) {
        this._ID = args;
        this.Node.id = args;
    }
});
//Mouse and Touch Event Handlers
Object.defineProperty(Button.prototype, "OnClick", {//Sets the onclick behavior
    set: function (args) {
        this.Node.onclick = args;
    }
});
Object.defineProperty(Button.prototype, "OnMouseUp", {//Sets the mousedown behavior
    set: function (func) {
        this.Node.onmouseup =func;
    }
});
Object.defineProperty(Button.prototype, "OnMouseDown", {//Sets the mousedown behavior
    set: function (func) {
        this.Node.onmousedown = func;
    }
});
Object.defineProperty(Button.prototype, "OnMouseEnter", {//Sets the mousedown behavior
    set: function (func) {
        this.Node.onmouseover = func;
    }
});
Object.defineProperty(Button.prototype, "OnMouseLeave", {//Sets the mousedown behavior
    set: function (func) {
        this.Node.onmouseout = func;
    }
});
Object.defineProperty(Button.prototype, "OnMouseWheel", {//Sets the mousedown behavior !Currently broken!
    set: function (func) {
        this.Node.addEventListener("mousewheel", func, false);//IE9, Chrome, Safari, Opera
        this.Node.addEventListener("DOMMouseScroll", func, false);//Firefox
    }
});

var x = new Button();
document.body.appendChild(x.Node);
x.CssClass = "productBtn";
x.ToolTip = "I am a tooltip";
x.ID = "Product ID";
Debug.WriteLine("x.cssClass: " + x.CssClass);
x.OnMouseUp =new System.EventHandler(clickTest);
x.OnMouseEnter = new System.EventHandler(clickTest);
Greg H-R
  • 83
  • 7