13
respostas

Problemas ao chamar função javaScript pelo button dinâmico

Bom dia pessoal.

Não sei se aqui alguém poderia me ajudar, pois estou com problemas para chamar uma função Javascript dentro do aspx. Sei que o aspx já está muito arcaico, mas o projeto foi desenvolvido nele e no momento não estou com tempo para atualizações. Vou inserir o código que já fiz e se alguém souber o que está ocorrendo e puder me ajudar: Preciso incluir um botão ao lado de textbox para que ao clicar neste seja exibido o conteúdo de valores da fórmula, ou seja, mais ou menos uma tabela assim ao clicar:

Codigo Empresa 1 Codigo Variável 123 Valor 20

Isto deve ser exibido para cada variável que compõem a fórmula. Até aqui tudo bem, fiz uma função do lado servidor e quero passá-la para o lado cliente com o Json. O problema ocorre pois como o botão é dinamico e só aparece para as variáveis que possuem fórmula, faço da seguinte forma para chamar no onclick do lado servidor a função javascript do lado cliente:

htmlDivsConteudoVariavel.Append("<div class = definicaoFormula><i class='botao-conteudo-formula'  onClick ='selecionaBotaoConteudoFormula(valorDaVariavelNumerico, htmlDivsDetalhesVariavel);'>...</i></div>");

No onclick chamo a função javaScript e está é responsável por recuperar o objeto e uma string Json do lado cliente. Sendo que ao clicar no botão aparece o seguinte erro no console:

Uncaught ReferenceError: showDivUpload is not defined
    at <anonymous>:1:1
    at Sys$_ScriptLoader$_loadScriptsInternal [as _loadScriptsInternal] (ScriptResource.axd?

Não sei se consegui ser clara. Se alguém puder me ajudar ficarei muito grata. Caso alguém queira entender melhor posso mandar meu código por private.

Desde já agradeço.

13 respostas

Oii Flávia! Não sei se entendi direito, mas vc precisa que os botões que são criados dinâmicamente também tenham eventos (que chamem uma função com click). Correto?

Se for isso, no momento seguinte que vc cria o botão dinamicamente, vc já tem que adicionar um evento nele, como um botao.on('click', function(){ ... }) ...Pq se vc fizer isto em outro momento pode dar erro de não encontrar o elemento alvo do evento em questão..

veja se te ajuda! abraços

Olá Vanessa. Agradeço muito sua ajuda mas acho que não consegui explicar direito a dúvida.

Vou detalhar melhor para ver se pode me ajudar:

Do lado cliente consegui capturar o click do botão, testei assim:

function selecionaBotaoConteudoFormula() { $("#botao-conteudo-formula").click(function () { console.log("Cliquei no botão"); });

Ao rodar este código é exibida a mensagem "Cliquei no botão" no meu console. Como vi que estava recuperando tentei fazer assim:

function selecionaBotaoConteudoFormula(valorDaVariavelNumerico) {
        var obj = valorDaVariavelNumerico;

          $ajax({
                type: 'GET',
                url: document.URL + '/montarTabelaConteudoFormula',
                contentType: "application/json; charset=utf-8",
                data: "{ 'obj':' " + valorDaVariavelNumerico + "' }",
                dataType: 'json',
                success: function (results) {

                    results.d;

                },
                error: function (results) { escreveMensagem(results.d); }
            });
            }

 }

Onde o quero é pegar um objeto que vem do lado servidor e retornar um string com a montagem da tabela. O método que chamo aqui é este:

[WebMethod] public static string montarTabelaConteudoFormula(ValorDaVariavelNumerico valorDaVariavelNumerico) {
        StringBuilder htmlDivsConteudoDetalhado = new StringBuilder();

        string formulaHtml = "";
        formulaHtml = valorDaVariavelNumerico.Variavel.formula.Replace('@', '<').Replace('#', '>');

        string[] separators = { "+", "-", "/", "*","(",")", " " };
        string value = classesComun.converterFormulaHtmlToString(formulaHtml);
        string[] variaveis = value.Split(separators, StringSplitOptions.RemoveEmptyEntries);
        foreach (var variavel in variaveis)
        {


            htmlDivsConteudoDetalhado.Append("<div class=\"div_conteudo_detalhes_relatorio\" id=\"" + valorDaVariavelNumerico.Variavel.codVariavel + "\">");
            htmlDivsConteudoDetalhado.Append("<table id='tabelaDetalhes' class='tabelaConteudoDetalhado'>" +
                    "<tr>" +
                        "<td class=\"td_identificacao_linha\"> Código Empresa: </td>" +
                        "<td>" + valorDaVariavelNumerico.Empresa.codEmpresa + "</td>" +
                    "</tr>" +
                     "<tr>" +
                        "<td class=\"td_identificacao_linha\"> Código Variável: </td>" +
                        "<td>" + valorDaVariavelNumerico.codVariavel + "</td>" +
                    "</tr>" +
                    "<tr>" +
                        "<td class=\"td_identificacao_linha\"> Valor: </td>" +
                        "<td>" + valorDaVariavelNumerico.valor + "</td>" +
                    "</tr>" +

                "</table>"
                );
        }
            htmlDivsConteudoDetalhado.Append("</div>");
           return htmlDivsConteudoDetalhado.ToString();


    }

O que preciso fazer: Ao clicar no botão exibir uma tabela com os detalhes da fórmula que está no objeto ValorDaVariavelNumerico- nesta entidade tem todo o detalhamento que necessito exibir na tabela.

Do lado servidor chamo o botão, pois o mesmo é dinâmico:

//Acrescentado botão para exibir os valores da fórmula

htmlDivsConteudoVariavel.Append("<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'>");
htmlDivsConteudoVariavel.Append("<i style='font-size:15px' id='botao-conteudo-formula' class='fa fa-info-circle' onClick ='selecionaBotaoConteudoFormula(valorDaVariavelNumerico);'></i>");

Quando executo e clico no botão ocorre o seguinte erro:

Uncaught ReferenceError: valorDaVariavelNumerico is not defined at HTMLElement.onclick (valoresVariaveisIndicador.aspx:1)

Estou com problemas com o objeto que estou passando como parâmetro e não sei se preciso passar desta forma.

Obrigada. Flávia

Olá Vanessa. Consegui resolver aquele problema. Vou postar o código atualizado, sendo que agora surgiu um outro problema que talvez possa me ajudar.

Ainda não cheguei na solução mas evolui bastante. Estou enviando o código atualizado e o erro que está ocorrendo agora, talvez possa me ajudar.

function selecionaBotaoConteudoFormula(elemento){ var elemento = $(this).data('elemento');

 $.ajax({
                type: 'GET',
                url: document.URL + '/montarTabelaConteudoFormula',
                contentType: "application/json; charset=utf-8",

                data: { 'elemento': elemento},
                   dataType: 'json',
                success: function (results) {

                    results.d;

                },
                error: function (results) { escreveMensagem(results.d); }
            });
    }
} 

Onde o que quero é pegar um objeto que vem do lado servidor e retornar um string com a montagem da tabela. O método que chamo aqui é este:

[WebMethod] public static string montarTabelaConteudoFormula(ValorDaVariavelNumerico valorDaVariavelNumerico) { StringBuilder htmlDivsConteudoDetalhado = new StringBuilder();

string formulaHtml = "";
formulaHtml = valorDaVariavelNumerico.Variavel.formula.Replace('@', '<').Replace('#', '>');

string[] separators = { "+", "-", "/", "*","(",")", " " };
string value = classesComun.converterFormulaHtmlToString(formulaHtml);
string[] variaveis = value.Split(separators, StringSplitOptions.RemoveEmptyEntries);
foreach (var variavel in variaveis)
{


    htmlDivsConteudoDetalhado.Append("<div class=\"div_conteudo_detalhes_relatorio\" id=\"" + valorDaVariavelNumerico.Variavel.codVariavel + "\">");
    htmlDivsConteudoDetalhado.Append("<table id='tabelaDetalhes' class='tabelaConteudoDetalhado'>" +
            "<tr>" +
                "<td class=\"td_identificacao_linha\"> Código Empresa: </td>" +
                "<td>" + valorDaVariavelNumerico.Empresa.codEmpresa + "</td>" +
            "</tr>" +
             "<tr>" +
                "<td class=\"td_identificacao_linha\"> Código Variável: </td>" +
                "<td>" + valorDaVariavelNumerico.codVariavel + "</td>" +
            "</tr>" +
            "<tr>" +
                "<td class=\"td_identificacao_linha\"> Valor: </td>" +
                "<td>" + valorDaVariavelNumerico.valor + "</td>" +
            "</tr>" +

        "</table>"
        );
}
    htmlDivsConteudoDetalhado.Append("</div>");
   return htmlDivsConteudoDetalhado.ToString();
}

O que preciso fazer: Ao clicar no botão exibir uma tabela com os detalhes da fórmula que está no objeto ValorDaVariavelNumerico- nesta entidade tem todo o detalhamento que necessito exibir na tabela.

Do lado servidor chamo o botão, pois o mesmo é dinâmico:

//Acrescentado botão para exibir os valores da fórmula

                    htmlDivsConteudoVariavel.Append("<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'>");
                    htmlDivsConteudoVariavel.Append("<i style='font-size:15px' id='botao-conteudo-formula' class='fa fa-info-circle' onClick ='selecionaBotaoConteudoFormula(this);'></i>");

Quando executo e clico no botão parou de ocorrer aquele erro e ocorre o seguinte erro:

Uncaught TypeError: Cannot read property 'toLowerCase' of undefined at escreveMensagem (Util.js:112) at Object.error (valoresVariaveisIndicador.aspx:1231) at j (jquery-2.1.1.min.js:2) at Object.fireWith [as rejectWith] (jquery-2.1.1.min.js:2) at x (jquery-2.1.1.min.js:4) at XMLHttpRequest. (jquery-2.1.1.min.js:4)

Andei pesquisando por este erro, mas até o momento sem solução.

Obrigada. Flávia

Desculpe este erro é de outro lugar. O erro que ocorre é :

Failed to load resource: the server responded with a status of 500 (Internal Server Error)

Obrigada. Flavia

Oii Flavia!

Sabia que você pode fazer tudo com Javascript sem precisar de uma função do backend para criar a tabela? Qual é o suporte à navegadores que vocês tem que dar? Pode usar EcmaScript6 (ES6)?

Bom vou analisar os trechos de código que vc enviou.

1) Botão dinâmico que chama uma função no click:

Aqui é um código asp né? Eu não sei asp, mas vou tentar...

// este código, de inserir um CSS, deveria ser inserido apenas 1x no arquivo, e não a cada botão! Não sei se está acontecendo isso, porém certifique-se ;)
htmlDivsConteudoVariavel.Append("<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'>");

//Aqui vc tem que interpolar ou concaternar "valorDaVariavelNumerico" pois parece que vc está passando uma string como parâmetro da função no onclick. O correto ficando assim:

htmlDivsConteudoVariavel.Append("<i style='font-size:15px' id='botao-conteudo-formula' class='fa fa-info-circle' onClick ='selecionaBotaoConteudoFormula("+valorDaVariavelNumerico+");'></i>");

2) Função selecionaBotaoConteudoFormula:

function selecionaBotaoConteudoFormula(valorDaVariavelNumerico) {

  //Aqui vc não precisa chamar o jquery click, pois esta função já estará sendo chamada nos clicks que vc colocou como atributo 'onclick' no botao

  $ajax({
    type: 'GET',
    url: document.URL + '/montarTabelaConteudoFormula',
    contentType: "application/json; charset=utf-8",
    data: JSON.stringify({obj: valorDaVariavelNumerico}),
    dataType: 'json',
    success: function (results) {

    //veja no console se esta retornando a resposta que vc precisa
        console.log(results.d);

        //Aqui vc pode pegar os retorno da api e passar para o seu método de montar a tabela.
        montarTabelaConteudoFormula(results.d)

    },
    error: function (results) { escreveMensagem(results.d); }
  });

}

Uma dúvida, o seu javascript está misturado com o front (views do asp), ou é um arquivo separado?

Pois de alguma maneira vc precisa passar o retorno da API para sua função asp... E isto eu também não sei te dizer como fazer, pois não conheço asp. Por isso que acho que seria melhor vc fazer tudo com JS para criar esta tabela...

Veja se com estas ideias ja te ajuda um pouco mais, vai me dizendo como está o progresso!

Olá Vanessa.

Agradeço mais uma vez sua ajuda. Quanto ao navegador seria só o chrome mesmo. Realmente posso fazer a montagem da tabela com javacript, mas ainda tenho dificuldades. Sou iniciante e programava em Java, me senti mas a vontade fazendo pelo backend com C#. O problema é que este universo de Json é tudo muito novo pra mim. Acho que estou mandando erradamente a url, pois quando ocorre o erro:

Failed to load resource: the server responded with a status of 500 (Internal Server Error) Olha a url que ele monta:

http://localhost:24803/Paginas/valoresVariaveisIndicador.aspx/montarTabelaConteudoFormula

Na minha opinião não deveria chamar explicitamente a minha função montarTabelaConteuFormula.

1) O que passo como parametro é um objeto .

2) Tentei modificar para alguns dados que passou e o erro continua o mesmo.

Agradeço muito sua ajuda e até gostaria de montar a tabela do lado Javascript mas preciso de mais conhecimento para isso. Vou tentar evoluir aqui e qualquer avanço coloco aqui.

Muito Obrigada. Flávia

Vanessa.

Percebo que capturei a url errada, veja:

http://localhost:24803/Paginas/valoresVariaveisIndicador.aspx/montarTabelaConteudoFormula?{%22obj%22:{}}

Ele tentar recuperar um objeto mas parece estar vazio.

Tentei passando this como parametro no onclick do botão.

Obrigada, Flávia

Flávia, vc como que teria que ser a url correta? Manda um exemplo dela pra mim

Então Vanessa, como sou iniciante estou com dúvidas a respeito. Mas acredito que esta função não deveria ser chamada do lado cliente, ou seja, a URL deveria ser esta:

http://localhost:24803/Paginas/valoresVariaveisIndicador.aspx

E ao clicar no botão a tabela apareceria sem a necessita de explitar o nome da função na url. O que acha?

Obrigada. Flávia

Certo. Quando realizamos um "ajax" (requisição assíncrona com javascript), estamos pedindo ao backend através do acesso a esta URL os dados (no caso aqui no formato JSON). Então quando vc faz:

type: 'GET',
url: document.URL + '/montarTabelaConteudoFormula',

Você estará pedindo a API (ou web service) da sua aplicação os dados, e esta url precisa existir e ser montada pelo seu backend, e quando vc acessar ela tem que ter um objeto javascript (JSON).

Então se esta url que vc está pedindo não existir, não vai adiantar tentar fazer um "ajax" nela. Por isso que perguntei se vc saberia a url correta, pois ela precisa ser programada antes de ser acessada por uma view.

Vou ver se consigo montar um exemplo com JS puro pra você.

Você já tentou conversar com seus colegas de trabalho sobre como pegar os dados e passar pro JS?

Oi Vanessa.

Acabei de ter uma reunião com um colega de trabalho e me esclareceu várias dúvidas. Vou tentar aplicar na prática esses conceitos e qualquer coisa te aviso.

Muito Obrigada. Flavia

Oii Flavia! Conseguiu fazer?

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software