6
respostas

[Bug] Botão Buscar(paciente) tráz lista JSON, mas não herança do filtro

Olá! O botão BUSCAR, que utilizamos para importar a lista pelo endereço: https://raw.githubusercontent.com/loresgarcia/Pacientes-API/master/pacientes.json, traz todos os dados da lista impressos na tabela, porém ao inserir o nome do paciente campo filtro, o array importado não sofre alterações, é possível apagá-los, mas não filtrá-los.

É possível verificar meus arquivos no meu repositório: https://github.com/PlinioCE/alura-aparecida-nutricionista

Obrigado pela atenção!

6 respostas

Oi, Plínio, tudo bem?

O problema ocorre porque você está usando a variável pacientes para iterar sobre os pacientes existentes no momento em que carrega a página, mas não há atualizações dessa variável quando novos pacientes são adicionados posteriormente.

Podemos solucionar esse problema, atualizando a variável pacientes no arquivo "buscar-pacientes.js", dentro do evento de clique no "xhr" sempre que um novo paciente for adicionado, utilizando o seguinte código:

pacientes = document.querySelectorAll(".paciente");

Com as modificações o código ficaria assim:

let botaoBuscar = document.querySelector("#buscar-paciente");

botaoBuscar.addEventListener("click", function () {
    let xhr = new XMLHttpRequest();
    xhr.open("GET", "https://raw.githubusercontent.com/loresgarcia/Pacientes-API/master/pacientes.json");

    xhr.addEventListener("load", function () {
        let respostaBusca = xhr.responseText;
        let buscaPacientes = JSON.parse(respostaBusca);
        buscaPacientes.forEach(function(paciente) {
            adicionarPacienteNaTabela(paciente);
        });

        pacientes = document.querySelectorAll(".paciente");
    });

    xhr.send();
});

Espero ter ajudado. Caso tenha dúvidas, estarei à disposição. Abraços e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!

Muitíssimo obrigado pela ajuda, Rodrigo! Você pode me ajudar a entender o lance das cores? Por que as cores só são aplicadas à tabela existente? Foi só uma coisa que fiz pra testar e dificultar, rsrsrs. Acabei me enrolando, mas acho que ficaria legal.

Oi, Plínio,

Muito legal sua ideia de criar uma legenda colorida para identificar o IMC dos pacientes.

O problema acontece, pois os estilos condicionais estão sendo aplicados antes da requisição GET e precisamos fazer com que essas cores sejam aplicadas após a requisição.

Podemos fazer com que essa legenda seja aplicada nos novos pacientes alterando algumas partes do código dos arquivos "calcula-imc.js" e "busca-pacientes.js".

Inicialmente todo o laço de repetição que você criou no arquivo "calcula-imc.js" para colocar a estrutura condicional para cada intervalo de IMC, precisa ser adicionado dentro de um função que iremos chamar de adicionaLegendaColorida() e em seguida iremos chamá-la. Ficaria assim:

function adicionaLegendaColorida() {
    let pacientes = document.querySelectorAll(".paciente");

    for (let index = 0; index < pacientes.length; index++) {

        let paciente = pacientes[index];

        let peso = paciente.querySelector(".info-peso").textContent;
        let altura = paciente.querySelector(".info-altura").textContent;

        let imc = paciente.querySelector(".info-imc");

        let pesoValido = validarPeso(peso);
        let alturaValida = validarAltura(altura);

        if (!pesoValido) {
            // pesoValido = false;
            imc.textContent = "Peso inválido!";
            paciente.classList.add("dado-invalido");
        }

        if (!alturaValida) {
            // alturaValida = false;
            imc.textContent = "Altura inválida!";
            paciente.classList.add("dado-invalido");
        }

        if (pesoValido && alturaValida) {
            let imcFormula = calcularImc(peso, altura);
            imc.textContent = imcFormula;

            if (imcFormula < 17) {
                paciente.classList.add("peso-muito-abaixo");
            }
            else if (imcFormula >= 17 && imcFormula < 18.5) {
                paciente.classList.add("peso-abaixo");
            }
            else if (imcFormula >= 18.5 && imcFormula < 25) {
                paciente.classList.add("peso-normal");
            }
            else if (imcFormula >= 25 && imcFormula < 30) {
                paciente.classList.add("peso-acima");
            }
            else if (imcFormula >= 30 && imcFormula < 35) {
                paciente.classList.add("peso-obesidade-I");
            }
            else if (imcFormula >= 35 && imcFormula <= 40) {
                paciente.classList.add("peso-obesidade-II");
            }
            else if (imcFormula > 40) {
                paciente.classList.add("peso-obesidade-III");
            }
        }
    }
}

adicionaLegendaColorida();

Em seguida feito isso, essa mesma função precisa ser chamada no arquivo "busca-pacientes.js" dentro do evento de clique no "xhr", após o comando que atualiza a variável pacientes. Ficaria assim:

let botaoBuscar = document.querySelector("#buscar-paciente");

botaoBuscar.addEventListener("click", function () {
    let xhr = new XMLHttpRequest();
    xhr.open("GET", "https://raw.githubusercontent.com/loresgarcia/Pacientes-API/master/pacientes.json");

    xhr.addEventListener("load", function () {
        let respostaBusca = xhr.responseText;
        let buscaPacientes = JSON.parse(respostaBusca);
        buscaPacientes.forEach(function(paciente) {
            adicionarPacienteNaTabela(paciente);
        });
        pacientes = document.querySelectorAll(".paciente");
        adicionaLegendaColorida();
    });

    xhr.send();
});

Dessa forma o resultado sera a legenda de cores aparecendo em todos os pacientes.

Espero ter ajudado. Caso tenha dúvidas, estarei à disposição. Abraços e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!

Deu certo, Rodrigo. Segui sua orientação. Porém, alguns detalhes que não estão funcionando muito bem.

1 - Ao atualizar a página, o filtro de busca dos pacientes não funciona; 2 - Ao adicionar um paciente, o mesmo é acrescentado à tabela, o filtro volta a funcionar, mas o novo paciente não recebe a legenda colorida; 3 - Ao fazer o upload da lista de pacientes via JSON, o filtro continua funcionando e os pacientes inseridos manualmente recebem a legenda colorida; 4 - Ao inserir um novo paciente após fazer o upload da lista, o mesmo não recebe a legenda.

Que aproveitar para agradecer sua atenção. Obrigado.

Obs.: Deixei atualizado no meu repositório.

Oi, Plínio,

O evento de input só é acionado quando o valor do elemento.filtro-paciente é alterado pelo usuário. Portanto, se você atualizar a página, o evento não será acionado automaticamente.

Uma solução para esse problema é envolver a lógica do filtro em uma função separada e chamar essa função tanto no evento de input quanto no evento de carregamento da página. Dessa forma, o filtro será aplicado quando o usuário interagir com o elemento de filtro ou quando a página for carregada.

let filtrarPaciente = document.querySelector(".filtro-paciente");
let pacientes = document.querySelectorAll(".paciente");

function filtrarPacientes() {
    if (filtrarPaciente.value.length > 0) {
        for (let indicePaciente = 0; indicePaciente < pacientes.length; indicePaciente++) {
            let filtroPaciente = pacientes[indicePaciente];
            let nomePaciente = filtroPaciente.querySelector(".info-nome");
            let filtroNome = nomePaciente.textContent;
            let expReg = new RegExp(filtrarPaciente.value, "i");
            if (!expReg.test(filtroNome)) {
                filtroPaciente.classList.add("invisivel");
            } else {
                filtroPaciente.classList.remove("invisivel");
            }
        }
    } else {
        for (let indicePaciente = 0; indicePaciente < pacientes.length; indicePaciente++) {
            let filtroPaciente = pacientes[indicePaciente];
            filtroPaciente.classList.remove("invisivel")
        }
    }
}

filtrarPaciente.addEventListener("input", filtrarPacientes);
window.addEventListener("load", filtrarPacientes);

Para que o novo paciente receba a legenda colorida, precisamos adicionar a função adicionaLegenda Colorida() no evento de clique adicionado à variável botaoAdicionarPaciente que está na linha e do arquivo "form.js". Ficaria assim:

botaoAdicionarPaciente.addEventListener("click", function (event) {
    event.preventDefault();
    let formularioPaciente = document.querySelector("#form-adicionar");
    let paciente = obterPacienteDoFormulario(formularioPaciente);

    let erroNome = verificarNome(paciente);
    if (erroNome.length > 0) {
        let msgErroNome = document.querySelector("#erro-nome")
        msgErroNome.textContent = erroNome;
        return msgErroNome;
    }

    let erroPeso = verificarPeso(paciente);
    if (erroPeso.length > 0) {
        let msgErroPeso = document.querySelector("#erro-peso")
        msgErroPeso.textContent = erroPeso;
        return msgErroPeso;
    }

    let erroAltura = verificarAltura(paciente);
    if (erroAltura.length > 0) {
        let msgErroAltura = document.querySelector("#erro-altura")
        msgErroAltura.textContent = erroAltura;
        return msgErroAltura;
    }

    let erroGordura = verificarGordura(paciente);
    if (erroGordura.length > 0) {
        let msgErroGordura = document.querySelector("#erro-gordura")
        msgErroGordura.textContent = erroGordura;
        return msgErroGordura;
    }

    adicionarPacienteNaTabela(paciente);
    adicionaLegendaColorida();

    formularioPaciente.reset();
});

Ao adicionar um novo paciente manualmente, também percebi que ao filtrar um paciente que já estava na lista, o paciente recém-adicionado era incluído no filtro, ou seja, filtrando o nome pesquisado e o nome do último paciente adicionado manualmente. Podemos solucionar isso, modificando a função adicionarPacienteNaTabela(paciente) para atualizar a lista de pacientes e, em seguida, chamar a função filtrarPacientes() para aplicar o filtro novamente. Assim, o novo paciente será incluído no filtro. Ficaria assim:

function adicionarPacienteNaTabela(paciente) {
    let itemTr = montarTr(paciente);
    let tabela = document.querySelector("#tabela-pacientes");
    tabela.appendChild(itemTr);

    pacientes = document.querySelectorAll(".paciente"); // Atualiza a lista de pacientes

    filtrarPacientes(); // Aplica o filtro novamente
}

Espero ter ajudado. Caso tenha dúvidas, estarei à disposição. Abraços e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!

Boa tarde, Rodrigo! Mais uma vez, meu muito obrigado a você! Deu tudo certo, funcionando "redondo". Cada dia que estudo, vejo que ainda não sei nada e que tenho que estudar cada vez mais. Vlw, pela força e paciência!!! Vou ficar bom o suficiente para tirar as dúvidas da galera nos fóruns. Abraço!