JavaScript function becomes "undefined" in addEventListener

1

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

JSFiddle: link

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 tested the following solutions, but they did not work:

I do not intend to use any library, it's a learning code.

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

    
asked by anonymous 29.06.2016 / 17:24

2 answers

3

The reason for this error is that by using addEventListener the this is changed to the one who fired the event or is the button . So the this found in the close function is not what you expect Dialog , but Button .

To work around this problem you can use the call and set a variable prior to the scope of addEventListener , which 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

29.06.2016 / 18:31
1

Hello, from what we talked about in the comments of your question, I think it's something related to the fact that you do not define dlg, within the Dialog function, so try to modify the code for 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);
}
    
29.06.2016 / 17:49