1

From my code I have a function that can create div elements multiple times (with surroundContents()), how can I make these created div elements to trigger a function inside the class of the very same page?

More precisely, I need that any of these div elements (created with function createDiv()) be able to trigger with click the function called clickCreatedDiv(arg) located in MyPage class and pass any string as an argument. I have tried this element.setAttribute('(click)', 'clickCreatedDiv()'); but with no success. How can I achieve this behavior?

export class MyProvider {
  wrapSelection(comment) {
    let element = document.createElement("div")
    element.setAttribute('(click)', 'clickCreatedDiv()');
    element.surroundContents(element);
  }
}

import { MyProvider } from '../../providers/my-provider';
@Component({
    selector: 'page-mypage',
    templateUrl: 'mypage.html',
}) 
export class MyPage {
  constructor(public myprovider: MyProvider) {}
  createDiv() {
    this.myprovider.wrapSelection();
  }

  clickCreatedDiv(arg) { // This is what I want to trigger with click
    alert('click ' + arg);
  }
}
7
  • 1
    Try setAttribute('onclick', 'clickCreatedDiv()') Commented Nov 21, 2018 at 23:44
  • @KoshVery that makes me get the message 'clickCreatedDiv is not defined'. Commented Nov 21, 2018 at 23:49
  • 1
    It means that onclick works, now you have to reach the function. Probably MyPage.clickCreatedDiv() would work? Commented Nov 21, 2018 at 23:56
  • 1
    onclick attribute function should be available from the global scope. Otherwise it would be better to set the event handler in that scope where clickCreatedDiv is available. Commented Nov 22, 2018 at 0:10
  • 1
    What string do you want to pass as an argument to clickCreateDiv? Is it the comment parameter of wrapSelection(comment)? Commented Nov 22, 2018 at 1:47

2 Answers 2

1

The Angular event binding syntax (click)="doSomething()" cannot be used to set the event handler on a dynamically created HTML element. To make it work, you can pass the event handler from the MyPage class, and set it with element.addEventListener:

export class MyProvider {
  wrapSelection(eventHandler) {
    let element = document.createElement("div")
    element.addEventListener("click", () => { eventHandler("Some text"); });
    ...
  }
}

In MyPage, the event handler should be defined as an arrow function to preserve this and allow to access the class members:

createDiv() {
  this.myProvider.wrapSelection(this.clickCreatedDiv);
}

clickCreatedDiv = (arg) => {
  alert('Clicked: ' + arg);
}

See this stackblitz for a demo.

Sign up to request clarification or add additional context in comments.

Comments

1

I would pass the click function as a callback to wrapSelection. E.g. something like:

export class MyProvider {
  wrapSelection(comment, onClick) {
    let element = document.createElement("div")
    element.setAttribute('(click)', onClick);
    element.surroundContents(element);
  }
}

export class MyPage {
  constructor(public myprovider: MyProvider) {}
  createDiv() {
    this.myprovider.wrapSelection('Some comment', this.clickCreatedDiv);
  }

  clickCreatedDiv(arg) { // This is what I want to trigger with click
    alert('click ' + arg);
  }
}

3 Comments

setAttribute('(click)', onClick) generates this error: "String contains an invalid character".
But using, setAttribute('onclick', onClick) renders this: <div onclick="function (arg) {alert('click ' + arg);}"></div>, but clicking it shows this error: function statement requires a name
Hmmm, what if you try: element.addEventListener("click", onClick);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.