Alura > Cursos de Front-end > Cursos de JavaScript > Conteúdos de JavaScript > Primeiras aulas do curso JavaScript: explorando a manipulação de elementos e da localStorage

JavaScript: explorando a manipulação de elementos e da localStorage

Adicionando tarefas - Apresentação

Olá, boas-vindas ao curso de JavaScript, onde vamos aprender um pouco mais sobre localStorage. Meu nome é Vinicios Neves, seu dev careca e barbudo favorito da Alura.

Audiodescrição: Vinicios Neves é uma pessoa de pele clara. Tem olhos castanho-escuros e é careca. Usa barba e bigode, óculos de grau com armação quadrada preta. Está com uma camisa preta e sentado em uma cadeira cinza. Ao fundo, parede lisa sem decorações com iluminação do azul ao rosa.

Vamos trabalhar juntos nessa jornada com a aplicação Fokus.

Dessa vez, vamos trazer um pouco do nosso dia a dia enquanto pessoas desenvolvedoras de front-end. Portanto, vamos evoluir uma aplicação existente.

Se você já a desenvolveu anteriormente no curso sobre manipulação de DOM, siga conosco para evoluí-la! Você precisará apenas fazer alguns ajustes para poder começar a jornada no Fokus.

Se você ainda não fez esse curso, não se preocupe, porque essa aplicação vai estar disponível para ser baixada em seu ponto inicial na atividade de "Preparando o Ambiente".

O que vamos aprender?

Nesse curso, vamos evoluir a aplicação de pomodoro. Além de controlar o tempo e tocar alguns sons dependendo do que aconteceu, vamos ter um CRUD (Create, Read, Update, Delete) na lista de tarefas.

Assim, poderemos selecionar, deletar e finalizar tarefas usando eventos customizados do JavaScript. Para chegar no resultado final, vamos aprender várias técnicas, inclusive técnicas de debug para procurar e corrigir bugs.

Se você já aprendeu a manipular o DOM e já fez os seus primeiros passos com o JavaScript dentro do navegador, você está apto(a) a evoluir esse projeto Fokus junto conosco.

Estamos te esperando no próximo vídeo!

Adicionando tarefas - Exibindo o formulário

Agora que já preparamos o nosso ambiente, já temos o projeto base disponível.

Conhecendo o projeto

No Figma do projeto, temos a seção de listagem de tarefas, que é onde vamos trabalhar no decorrer desse curso.

Seção de lista de tarefas da aplicação Fokus. Em fundo azul, título "Lista de tarefas" seguido por uma lista com três itens: "Tarefa concluída", "Tarefa pendente" e "Tarefa pendente". Abaixo, uma caixa de texto intitulada "Adicionando tarefa". Nela, temos as opções de "Deletar", "Cancelar" e "Salvar". Na parte inferior, botão "Adicionar nova tarefa".

Nele, temos um formulário com o qual precisamos interagir.

Vamos abrir o projeto no VS Code, onde temos o index.html, uma pasta "imagens", uma pasta "sons", dois scripts JavaScript, um que se chama script.js e outro script-crud.js. E também um arquivo CSS, styles.css. Esse é o nosso projeto base.

Nas extensões do VS Code (atalho "Ctrl+Shift+X"), temos instalada a extensão chamada Live Server, e vamos usá-la para rodar o projeto em tempo real.

E o que ela faz? Ela nos dá a opção "Go Live" no canto inferior direito do VS Code que vai subir com o servidor web. Assim, vamos conseguir interagir e navegar pelo nosso projeto.

Ao clicar em "Go Live", ele carregar e abrir o Fokus no navegador. Já temos alguns elementos prontos, pois herdamos arquivos HTML e CSS. Por isso, vamos precisar trabalhar em cima disso.

Monitorar clique do botão

O primeiro passo é monitorar o clique no botão "Adicionar nova tarefa". Atualmente, se clicamos nesse botão, não acontece nada. Porém, no Figma, esse botão vai alternar entre esconder ou exibir o formulário de adicionar tarefa.

No VS Code, vamos acessar a estrutura de pastas clicando em "Explorer" (atalho "Ctrl + Shift + E") e abrir o script-crud.js, pois é nele que vamos escrever o código.

Nesse primeiro momento, precisamos encontrar o botão "Adicionar Tarefa". Para buscar esse botão Adicionar Tarefa, vamos chamar o document, que é o responsável que vai nos dar a API de interação com o DOM. E vamos chamar o método que busca esses elementos que vamos precisar. Nesse momento, vamos usar o querySelector().

script-crud.js:

// encontrar o botão adicionar tarefa
document.querySelector('')

Esse método querySelector aceita vários seletores diferentes. Qualquer seletor CSS válido serve para ele. Ele vai procurar, verificar se tem algum elemento que tenha aquele seletor. Se ele encontrar, ele retorna o primeiro que achou.

Como vamos buscar isso? Vamos procurar no HTML do projeto que herdamos. Nessa situação, pode não ter sido você que o iniciou. Portanto, vamos buscar do jeito mais simples.

Dica: Para focar no código, você pode colapsar a estrutura de pastas com o atalho "Ctrl + B" no Windows ou "Command + B" no Mac.

Vamos fazer um "Ctrl + F" para buscar dentro do index.html e procurar por "Adicionar nova tarefa". Esse é o elemento que temos que encontrar.

index.html:

<button class="app__button--add-task">
        <img src="/imagens/add_circle.png" alt=""> Adicionar nova tarefa
</button>

Esse elemento da linha 122 tem uma classe que se chama app__button--add-task, que significa botão de adicionar tarefa em inglês. Com isso, temos uma classe bem específica e podemos usá-la para selecionar o elemento. Vamos copiá-la.

No script-crud.js, vamos colá-lo em querySelector() adicionando um ponto antes da classe. Estamos fazendo um exercício de leitura de código para buscar o código que alguém fez com o qual precisamos interagir.

Agora que já selecionamos esse elemento, vamos guardá-lo em uma referência. Para isso, vamos guardar document.querySelector() em uma constante chamada de btnAdicionarTarefa, que é para dar a ideia de que é um botão.

// encontrar o botão adicionar tarefa
const btnAdicionarTarefa = document.querySelector('.app__button--add-task')

Agora que já buscamos esse elemento, vamos chamar esse btnAdicionarTarefa e vai fazer um .addEventListener(). Ou seja, queremos capturar o evento de clique nesse botão. Para isso, devemos receber dois parâmetros entre os parênteses.

O primeiro é qual o evento que queremos ouvir. Vamos dizer que queremos ouvir o evento de click entre aspas.

O segundo parâmetro é uma função, usando () -> {}. Ou seja, o que queremos executar quando esse elemento for clicado.

btnAdicionarTarefa.addEventListener('click', () => {
    formAdicionarTarefa.classList.toggle('hidden')
})

Voltando lá no index.html, agora precisamos interagir com o formulário. O elemento logo acima desse botão que procuramos é o formulário.

index.html:

<form class="app__form-add-task hidden" aria-hidden="true">
        <!-- Código omitido… -->
</form>

O formulário tem uma classe específica e também uma classe hidden. Vamos pegar essa classe hidden e vamos acessar o styles.css para verificar o que essa classe faz. Aparentemente a ideia dessa classe é esconder algo.

Vamos abrir o arquivo styles.css, que está na raiz do projeto, e vamos novamente usar o "Ctrl + F" para procurar pela classe hidden.

styles.css:

.hidden {
    display: none;
}

Essa classe presente na linha 305 dá um display: none, ou seja, ela esconde o formulário.

O que temos que fazer quando alguém clicar nesse botão? Alternar. Se essa classe já existe no elemento, remove a classe. Se não tem, coloca a classe.

Vamos aproveitar que já sabemos como selecionar um elemento e vamos selecionar também o formulário. Para isso, vamos pegar a classe desse formulário, app__form-add-task e guardar também em uma referência.

Na linha 4, logo depois de fazer a busca pelo btnAdicionarTarefa, vamos criar uma nova constante chamada formAdicionarTarefa que também vai receber um document.querySelector(), passando o seletor CSS e a classe do formulário. Ou seja, ponto e app__form-add-task.

script-crud.js:

const formAdicionarTarefa = document.querySelector('.app__form-add-task')

Agora que temos esse elemento, quando alguém clicar, podemos chamar o formulário formAdicionarTarefa e pegar a lista de classes desse formulário, usando .classList.

Existem vários métodos disponíveis para interagir com essa lista de classes. Um desses métodos é o toggle().

É tão comum ter esse conceito de "Se tem, tira. Se não tem coloca", que a própria API do DOM já nos entrega um método. Com ele, podemos fazer o toggle, ou seja, a alternância dessa classe.

Vamos chamar o .toggle() após classList. Qual a classe em que queremos fazer essa troca? A classe hidden.

Podemos fazer um copia e cola para não errar a grafia do nome da classe do form. Basta copiar a classe hidden na linha 102 do index.html. O que devemos fazer é colá-la nesse classList.toggle().

btnAdicionarTarefa.addEventListener('click', () => {
    formAdicionarTarefa.classList.toggle('hidden')
})

Recapitulando, procuramos dois elementos: o botão btnAdicionarTarefa e o formulário formAdicionarTarefa. Quando alguém clica no botão, fazemos a alternância da classe hidden no formulário.

Vamos verificar se o código que escrevemos vai funcionar. No navegador, voltamos na aba do Fokus, que está rodando na 127.0.0.1, que é o IP da própria máquina, o localhost, na porta 5500.

Vamos recarregar a página e clicar no botão "Adicionar nova Tarefa". Com isso, é exibido o formulário para adicionar uma nova tarefa.

A primeira missão dada já está cumprida, conseguimos exibir o formulário. Sendo que o contrário também deve acontecer. Se clicamos de volta no botão, o formulário é escondido e tudo funciona como desejado.

Adicionando tarefas - Submetendo o formulário

Agora que já entendemos como interagir com o botão de "Adicionar nova tarefa" que exibe o formulário, vamos interagir com o formulário e o textarea (caixa de texto) que tem lá dentro. Vamos para o código?

Monitorar envio do formulário

Vamos abrir o VS Code e acessar o arquivo index.html. Na linha 107, existe uma classe da tag <textarea>, que é justamente a app__form-textarea. Vamos usar para selecionar e fazer a consulta no DOM.

index.html:

<textarea required rows="4" class="app__form-textarea" placeholder="No que você está trabalhando?"></textarea>

Após copiar a classe com o atalho "Ctrl + C", vamos no script-crud.js. Na linha 5, após as demais contantes, vamos criar mais um const textarea. Como só teremos um textarea, vamos deixar somente esse nome e chamar a API de document.querySelector() que recebe um seletor CSS válido dessa classe.

Repara que colocamos o ponto antes da classe, porque é um seletor CSS. Sem o ponto não é uma classe CSS e o querySelector() não vai conseguir encontrar o que estamos buscando.

script-crud.js:

const textarea = document.querySelector('.app__form-textarea')

Agora que já temos o textarea para conseguir interagir com o que a pessoa usuária digitou, podemos nos enfocar no formulário. Na linha 9, depois de ouvir o evento de clique, vamos chamar o formAdicionarTarefa, que é uma referência ao formulário.

Quando buscamos um elemento, estamos guardando ele numa constante para que seja possível interagir com ele a qualquer momento - assim como fizemos para o formAdicionarTarefa.

Nele, vamos colocar mais um listener, algo para escutar o evento, utilizando o método addEventListener().

E qual o evento que queremos dessa vez? Queremos o evento de submissão, ou seja, quando alguém envia esse formulário. Por isso, queremos ouvir o evento de submit. Passamos como segundo parâmetro uma função (() => {}).

Dessa vez, vamos precisar ter acesso ao evento e já vamos te dizer o porquê.

formAdicionarTarefa.addEventListener('submit', (evento) => {

})

Com isso, adicionamos um listener no formAdicionarTarefa, ou seja, alguém que fica ouvindo e está preparado para reagir quando aquele evento de submit for ativado.

Quando alguém submeter esse formulário, precisamos tirar o comportamento padrão desse componente.

No navegador, vamos preencher uma tarefa na caixa de texto, por exemplo, "estudar TypeScript". Quando clicamos em "Salvar", a página recarrega. Ou seja, existe um comportamento do navegador que tenta enviar isso para algum lugar e faz um refresh. Porém, não queremos que a aplicação Fokus faça isso.

Para conseguir interagir com esse evento e impedir que isso aconteça, vamos pegar o evento que recebemos por parâmetro. No VS Code, vamos chamar o evento e vamos chamar um método desse evento que se chama preventDefault().

formAdicionarTarefa.addEventListener('submit', (evento) => {
        evento.preventDefault();
})

O que esse método vai fazer? Ele vai impedir o comportamento padrão, como seu nome indica.

Vamos salvar o arquivo e voltar no navegador. Após recarregá-lo, vamos exibir o formulário clicando em "Adicionar nova tarefa" e preencher o campo com "estudar TypeScript". Quando clicamos em "Salvar", o navegador não recarrega, pois não tem mais aquele comportamento, como queríamos.

Criar uma lista de tarefas

O que temos que fazer agora? Vamos pegar o valor digitado no textarea e guardar em uma variável. Dentro da função, logo depois de fazer o preventDefault(), vamos criar mais uma constante chamada descricaoTarefa.

A descrição da tarefa vai receber justamente o valor do textarea. Como fazemos para ter acesso ao valor digitado na caixa de texto? Vamos chamar o textarea que já selecionamos com o querySelector(). Em seguida, vamos adicionar um ponto e chamar a propriedade value para pegar o valor digitado.

Como o textarea é um valor de interação com a pessoa usuária, já temos acesso ao que foi preenchido.

formAdicionarTarefa.addEventListener('submit', (evento) => {
        evento.preventDefault();
        const descricaoTarefa = textarea.value
})

Com isso, podemos criar agora um objeto que representa uma tarefa. Portanto, vamos criar outra constante chamada tarefa. Essa tarefa recebe um objeto. Como já estamos num objeto que se chama tarefa, vamos dizer que a descricao é justamente esse valor que acabamos de pegar.

Porém, não é preciso gravar a descrição em uma variável só para colocá-la no objeto. Por isso, vamos remover por completo a linha de const descricaoTarefa e chamar diretamente o textarea.value entre as chaves de const tarefa.

formAdicionarTarefa.addEventListener('submit', (evento) => {
        evento.preventDefault();
        const tarefa = {
                descricao: textarea.value
        }
})

Agora, essa tarefa precisa ir para alguma lista, pois precisamos guardá-la em algum lugar.

Na linha 6, antes de colocar o primeiro EventListener, vamos criar uma constante chamada tarefas que será a lista de tarefas. Como ela é uma lista, vamos iniciá-la como um array vazio.

const tarefas = []

Voltando para a função de submit, depois de criar o objeto que representa uma tarefa, vamos chamar o tarefas.push() passando tarefa. Assim, guardamos a tarefa que acabamos de criar dentro da lista tarefas.

Guardar tarefas no armazenamento local

Qual é o próximo passo? Precisamos guardar a lista em algum lugar. Todas as variáveis que codamos só existem em tempo de execução na memória. Toda vez que recarregamos a aplicação, elas são recriadas. Então, entre um refresh do navegador e outro, as nossas informações são perdidas.

Para persistir os dados entre sessões, precisamos guardá-los em algum lugar. Existem algumas opções para fazer isso, mas nesse curso vamos usar o localStorage.

Logo depois de fazer o tarefas.push(tarefa) para colocar a tarefa na lista, vamos chamar o localStorage. Esse armazenamento local nos dá uma API que nos permite interagir, colocar, remover, limpar tudo que está lá dentro.

Nesse caso, queremos colocar um item lá dentro, por isso, vamos usar o método setItem(). Que item é esse? Como primeiro parâmetro, vamos passar tarefas entre aspas, porque queremos guardar a lista inteira de tarefas lá dentro. Em outras palavras, passamos uma string tarefas, que é a chave de acesso para esse valor.

O segundo parâmetro que devemos passar é o valor em si, que é a lista de tarefas. Por isso, vamos passar a variável tarefas.

formAdicionarTarefa.addEventListener('submit', (evento) => {
        evento.preventDefault();
        const tarefa = {
                descricao: textarea.value
        }
        tarefas.push(tarefa)
        localStorage.setItem('tarefas', tarefas)
})

Vamos recapitular. Temos uma variável que se chama tarefa, que identifica a tarefa que estamos cadastrando nesse momento. Também temos uma lista de tarefas com todas as tarefas sendo geridas pelo Fokus. Pegamos esse conceito de tarefas e guardamos no localStorage.

Será que conseguimos verificar se isso funciona? Após salvar, vamos no navegador e abrir o developer tools (ferramentas do desenvolvedor) com "F12". Dentre as abas do DevTools, vamos acessar a aba application (aplicação).

Dentro dessa aplicação, está o Local Storage, onde temos a URL da nossa aplicação, que é 127.0.0.1:5500. Se tiver algum dado guardado, podemos limpá-lo clicando com botão direito e selecionando "Clear". Assim, não temos nada no localStorage.

Para testar, vamos recarregar a página e clicar no botão em "Adicionar nova tarefa". Vamos colocar a descrição da tarefa como "estudar TypeScript" e clicar em "Salvar".

KeyValue
tarefas[object Object]

Repara que algo aconteceu, porque uma tarefa foi parar no localStorage com o valor object Object. Tem algo errado com esse value e precisamos corrigi-lo na sequência.

Sobre o curso JavaScript: explorando a manipulação de elementos e da localStorage

O curso JavaScript: explorando a manipulação de elementos e da localStorage possui 133 minutos de vídeos, em um total de 53 atividades. Gostou? Conheça nossos outros cursos de JavaScript em Front-end, ou leia nossos artigos de Front-end.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda JavaScript acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas