0

I created a SharePoint Framework Webpart.

I call a webservice that returns some data from sharepoint (terms from termstore), and for each term i generate an html that display the term. On the onclick of each term i want to call a typescript function, passing the term as parameters, to get its children terms.

This code below create the following wrong behaviour: when the webpart is displayed, it automatically calls the function this.readIterm when I didnt even click on it !

Am I missing something or by design doing it the wrong way ? I tried to replace onclick="${this.readIterm(term)}" by onclick="readIterm($(term))" but it does nothing.

Code below

terms.forEach(term => {
              htmlContent +=
                `<div class="w3-card w3-third w3-margin-bottom" style="" onclick="${this.readIterm(term)}">
                      <header class="w3-container w3-blue">
                        <h1>Header</h1>
                      </header>
                    <div class="w3-container">
                      <span>${term.name}</p>
                    </div>
                    <footer class="w3-container w3-blue">
                      <h5>Footer</h5>
                    </footer>
                    </div>`

This html is then added to this.domElement.innerHTML, displaying it in the webpart.

public readIterm(myTerm: ITerm) { alert("readIterm is clicked"); }

Thank you in advance for your help and guidance if I do not follow best practice !

Jeff

2 Answers 2

2

There is one more way to attach event listener.

Refer below code sample. This works perfectly for me: (Note: This is a basic idea. You can refer this code and make changes to yours accordingly.)

public render(): void{ 

this.domElement.innerHTML = ` <div class="form-group">
   <button class="btn btn-success" id="btnReadAllItems">
      <span class="ms-Button-label">Read All Items</span>
   </button>
   <button class="btn btn-success" id="btnReadItemById">
      <span class="ms-Button-label">Read Item By Id</span>
   </button>
</div>`; 
this._setButtonEventHandlers(); 

}



private _setButtonEventHandlers(): void {
   const webPart: SpfxCrudWebPart = this;
   this.domElement.querySelector('#btnReadAllItems').addEventListener('click', () => {
      this._GetListItemsNF();
   });
}


private _GetListItemsNF(): void {
   // 
   //
   //
}

Another way is as below. (But you will have to make some changes according to your code)

public render(): void{ 
      htmlContent +=
        `<div class="w3-card w3-third w3-margin-bottom" id="test">
              <header class="w3-container w3-blue">
                <h1>Header</h1>
              </header>
            <div class="w3-container">
              <span>${term.name}</p>
            </div>
            <footer class="w3-container w3-blue">
              <h5>Footer</h5>
            </footer>
        </div>`
    }

    this._setButtonEventHandlers(); 

    this.myTerm = term;  // Here we are assigning value to the `myTerm` variable. And `myTerm` is a public property, So value of `myTerm` will be accessible using `this.myTerm`
}


public myTerm: ITerm; // here we are declaring `myTerm` variable

public readIterm():void{

    // here you can access the cariable `myTerm` using `this.myTerm`.

    // alert(this.myTerm);

    // alert("readIterm is clicked"); 

}

private _setButtonEventHandlers(): void {
   this.domElement.querySelector('#test').addEventListener('click', () => { this.readIterm(); });
}
Sign up to request clarification or add additional context in comments.

3 Comments

I cant get it work with your solutions because Im getting terms from term store, for each term i generate an HTML To display it. On clicking on the term i need to pass the selected term, that is why i wanted to do smth like that : onclick="${this.readIterm(term)}"> maybe this is not the good practice. Thanks for your time :)
please refer the above answer. I have updated and added one more approach. You can try this way.
Hi thanks for your help I think I can fill an array of term object, then iterate those objects (my terms), and call the onclick and pass the object as parameter. I dont know if this is the good design. Maybe react helps for that ?
0

Rather onClick instead of onclick. Then check to make sure that you get into your "readIterm" method by calling the console (console.log).

6 Comments

it gets into readIterms as the code defined. But without even clicking. It gets inside each time a term is displayed;
But where does your method come from? Is it included in your module? Or else imported? If your method is imported, then call it there directly (eg {maMethode ()}, no need for this). Otherwise if it is passed in parameter of your module then declares there in local before calling it. Hoping to have helped.
the method is in the same TS file
public readIterm(myTerm: ITerm) { alert("readIterm is clicked"); }
If you want to perform the action by clicking, then you will have to declare in your module the method to attach it to the event (ex: const readIterm_ = event => () {readIterm ()}). Unless you explicitly pass the method to the module, I do not see how you could call a server method from your module (knowing that the context of your module is partitioned in {}).
|

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.