1

Im making a program that dynamically creates html elements and when you click any of those elements it should display its value in another textbox. This is the class im using to define the element:

class msg_element{
  constructor(msg){
    this.message = msg;

    this.element = document.createElement("P");
    this.element.innerHTML = this.message;
    this.element.addEventListener("click", function(){
      document.getElementById("update").value = this.message;
    });

    document.getElementById("textview").appendChild(this.element);
  }
}

and this is the loop that creates the elements:

for(var i = 0; i < bmg_msg.length; i++){
    var element = new msg_element(bmg_msg[i]);
  }

it creates all the elements correctly, but the clicking function doesnt work, it just displays "undefined" in the textbox. What can I do to fix this?

Billy
  • 15
  • 4
  • can you show complete example of your code including html js and css? – DCR Nov 17 '19 at 17:19
  • 2
    The value of `this` inside the event listener won't be the same as `this` in the constructor function. You could use an `=>` function instead of a regular function, or you could explicitly store `this` in a separate local variable in the constructor. – Pointy Nov 17 '19 at 17:20

2 Answers2

2

The line

    this.element.addEventListener("click", function(){
      document.getElementById("update").value = this.message;
    });

is the problem. When you create the callback you define it as function(){...}. The problem with that is that it causes this to refer to the event target. To fix this you can either:

Use an Arrow function so that this will refer to the current class instance.

    this.element.addEventListener("click", ()=>{
      document.getElementById("update").value = this.message;
    });

or create a variable to store the reference to the constructor

    let _this = this;
    this.element.addEventListener("click", function(){
      document.getElementById("update").value = _this.message;
    });
Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
KolCrooks
  • 514
  • 1
  • 5
  • 12
1

In this portion of your code:

this.element.addEventListener("click", function(){
  document.getElementById("update").value = this.message;
});

Beware: this outside of the click handler is different from this inside of it.

Inside event handlers, this always points to the DOM element that fired the event (in your case it's the paragraph you're creating).

A possible fix would be to use a variable which will hold the value of this.message, e.g.:

var myMessage = this.message;
this.element.addEventListener("click", function(){
  document.getElementById("update").value = myMessage;
});
Anis R.
  • 6,656
  • 2
  • 15
  • 37