Doubt how to declare a class function directly in HTML

Asked

Viewed 38 times

-1

I’m having trouble calling an event function when I dynamically rewrite HTML. I’m using pure javascript. Both functions are in a class file class tabela, but when I click on the link that calls the function this.changePage('i') she says there is no function. There is another way for me to declare this function next to HTML?

Below is the function that mounts the template:

templatePagination(data, numRegPerPage, page)
{
    let numReg = data.length;
    this.pages = Math.ceil(numReg/numRegPerPage);
    let html = `
    <nav aria-label="Page navigation example">
    <ul class="pagination">
        <li class="page-item">
        <a class="page-link" href="#" aria-label="Previous" onclick="previousPage()">
            <span aria-hidden="true">&laquo;</span>
            <span class="sr-only">Previous</span>
        </a>
        </li>`;
        for(let i=1; i<= this.pages; i++){
            if(this.pages>1){
                html += `<li class="page-item"><a class="page-link" onclick="${this.changePage('i')}">${i}</a></li>`;
            }
        }
        html += `
        <li class="page-item">
        <a class="page-link" href="#" aria-label="Next" onclick="nextPage()">
            <span aria-hidden="true">&raquo;</span>
            <span class="sr-only">Next</span>
        </a>
        </li>
    </ul>
    </nav>`;

    return html;
}

And the function that should be called:

changePage(pageSelected)
    {
        this.index = pageSelected;
        this.updateTemplate();
    }

1 answer

3


This way there is no way to test, but what I can tell you is that the way you are going through the function will not work.

You are not actually declaring a function to be invoked in the event onclick, you are actually invoking the function and passing the return to the onclick.

Should be

`<li class="page-item"><a class="page-link" onclick="this.changePage(${i})">${i}</a></li>`

However That won’t work either. In this way that you are generating HTML, you are first generating only one string, and eventually interpreting this string as HTML. But strings don’t understand the context of this.

In invoking this.changePage, the code interpreter will not understand that the this refers to a specific object, this.changePage is just a string, and therefore this function changePage will be invoked in the context of its element (if there is a function with that name), not in its object.

If you need to attach the context of your object to the onclick you will need another approach. It is not something so simple.

A strategy would be for example to parse from your string to HTML and then do the Binding of this in the function; basically changing the context of this to your object:

let html = `
    <nav aria-label="Page navigation example">
        <ul class="pagination">
            <li class="page-item">
            <a class="page-link" href="#" aria-label="Previous" onclick="previousPage()">
                <span aria-hidden="true">&laquo;</span>
                <span class="sr-only">Previous</span>
            </a>
            </li>`;

            for (let i=1; i<= this.pages; i++) {
                html += `<li class="page-item"><a class="page-link" onclick="this.changePage(${i}")>${i}</a></li>`;
            }

            html += `
            <li class="page-item">
            <a class="page-link" href="#" aria-label="Next" onclick="nextPage()">
                <span aria-hidden="true">&raquo;</span>
                <span class="sr-only">Next</span>
            </a>
            </li>
        </ul>
    </nav>`;

let base = document.createElement('div'); // crio um elemento qualquer como base
base.innerHTML = html; // a string recebida é interpretada como html

base.querySelector('.page-item').forEach(elem => elem.onclick = elem.onclick.bind(this)); // faço o binding do this com a função do evento onclick
return base.firstElementChild; // retorno o html

In note: as you are returning an HTML, and not a string in HTML format, to add this content to your page should be via the method appendChild.

  • I actually did something similar to your answer. I put the addEventListener after rendering the html: document.querySelector(.page-item).addEventListener("click",()=>{&#xA; this.changePage(page)&#xA; }). So it worked. Thank you.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.