Javascript function becomes "Undefined" in addeventlistener

Asked

Viewed 205 times

1

Reformulated question: I’m trying to create a dialog for the user, but I’m having an error described as Uncaught TypeError: Cannot read property 'style' of undefined when I click the button Close generated by the code.

Jsfiddle: https://jsfiddle.net/jh3funk2/

The code is this:

    /** Dialog **/

    var Dialog = function(name, width)
    {
        // Cria frame do dialog
        var dlgFrame = document.createElement('div');
        dlgFrame.id = name;
        dlgFrame.style.display = 'none';
        dlgFrame.setAttribute("data-dialog", name);

        // Cria o container para os componentes
        var dlgContainer = document.createElement('div');
        dlgContainer.style.width = width;
        dlgContainer.setAttribute("data-dialog-width", width);

        // Cria espaço para o título
        var dlgTitle = document.createElement('div');
        dlgTitle.setAttribute("data-dialog-title", name);

        // Cria espaço para os botões
        var dlgButton = document.createElement('div');
        dlgButton.setAttribute('data-dialog-buttons', name);

        // Monta os componentes
        dlgContainer.appendChild(dlgTitle);
        dlgContainer.appendChild(dlgButton);
        dlgFrame.appendChild(dlgContainer);
        document.body.appendChild(dlgFrame);

        // Cria as variáveis
        this.dlg = document.querySelector('[data-dialog="'+name+'"]');
        this.title = document.querySelector('[data-dialog-title="'+name+'"]');
        this.buttons = document.querySelector('[data-dialog-buttons="'+name+'"]');
    }

    Dialog.prototype.show = function(display)
    {
        this.dlg.style.display = display || "flex";   
    };

    Dialog.prototype.close = function()
    {
        this.dlg.style.display = 'none';
    };

    Dialog.prototype.setTitle = function(title)
    {
        this.title.innerHTML = title;
    }

    Dialog.prototype.addButton = function(text, callback)
    {
        // Cria os elementos
        var button = document.createElement('button');
        var text = document.createTextNode(text);

        // Define o texto e o evento
        button.appendChild(text);
        button.addEventListener("click", function()
        {
            // todo: verificação do typeof
            callback();
        });

        this.buttons.appendChild(button);   
    }

    /** Controlador **/

    appController = function()
    {
        this.confirmarSaida;
    };

    appController.prototype.init = function()
    {
        this.confirmarSaida = new Dialog('confirmarSaidaDlg', '10vw');
        this.confirmarSaida.setTitle('Deseja sair do sistema?');
        this.confirmarSaida.addButton('Fechar', this.confirmarSaida.close);
        this.confirmarSaida.show();
    };

    window.onload = function()
    {
        appController = new appController();
        appController.init();
    };

I have tested the following solutions, but they have not worked:

I don’t intend to use any library, it’s a code for learning.

How to make the dialog close with the function by clicking the button close? Remember that I will also pass other callbacks to the button, not only the this.close();

  • 1

    While executing your code I did not get the error you reported, I got the following error, Uncaught Typeerror: this.confirmaSaida.setTitle is not a Function(...), this did not happen to you either?

  • 1

    The methods are missing setTitle and setButton;

  • 1

    Checking I noticed that there is a property called this dlg., what would be generating this error. You should define it. I believe it is this.dlg = dlgFrame, but you must check

  • You’re right, I forgot most of the code when passing to Stackoverflow, I’ll modify the question, thank you.

  • I’m voting to close, not to generate hypothetical answers, until it can be reopened with the real situation.

  • @Guilhermelautert the question is already corrected.

Show 1 more comment

2 answers

3


The reason for this error is that when using addEventListener the this is changed to who shot the event or is the button.
So the this who is in the role close is not what you expect Dialog, and yes Button.

To solve this problem you can use the method call and set a variable prior to the scope of addEventListener, that will be used in the method.

Dialog.prototype.addButton = function(text, callback)
{
    // Cria os elementos
    var button = document.createElement('button');
    var text = document.createTextNode(text);

    var self = this;

    // Define o texto e o evento
    button.appendChild(text);
    button.addEventListener("click", function()
    {
        // todo: verificação do typeof
        callback.call(self);
    });

    this.buttons.appendChild(button);   
}

Related questions

  • 1

    It worked perfectly William, thank you very much, I will read the related questions you posted.

1

Hello, from what we talked about in the comments of your question, I believe it is something related to the fact that you do not define dlg, within the Dialog function, so try to modify the code to the following:

var Dialog = function(name, width)
{
    //código adicionado
    this.dlg = {};

    // Cria frame do dialog
    var dlgFrame = document.createElement('div');
    dlgFrame.id = name;
    dlgFrame.setAttribute("data-dialog", name);

    // Cria o container para os componentes
    var dlgContainer = document.createElement('div');
    dlgContainer.style.width = width;
    dlgContainer.setAttribute("data-dialog-width", width);

    // Cria espaço para o título
    var dlgTitle = document.createElement('div');
    dlgTitle.setAttribute("data-dialog-title", name);

    // Cria espaço para os botões
    var dlgButton = document.createElement('div');
    dlgButton.setAttribute('data-dialog-buttons', name);

    // Cria espaço para os botões
    var dlgButton = document.createElement('div');
    dlgButton.setAttribute('data-dialog-buttons', name);

    // Monta os componentes
    dlgContainer.appendChild(dlgTitle);
    dlgContainer.appendChild(dlgButton);
    dlgFrame.appendChild(dlgContainer);
    document.body.appendChild(dlgFrame);
}
  • You’re right, I forgot most of the code when passing to Stackoverflow, I will modify the question, thank you.

  • But was that the problem? solved?

  • 1

    This will not solve the problem because setar this.dlg = {} just makes it an object, it will continue not having the method style necessary in the Dialog.prototype.show

  • Okay, but he said that in his code, he has this method, just forgot to put, so it might work.

  • I corrected the question with the full code

Browser other questions tagged

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