Tag: front-end

  • Como centralizar verticalmente elementos HTML com CSS

    Como centralizar verticalmente elementos HTML com CSS

    Uma das coisas mais comuns, mas ao mesmo tempo mais chatas de se fazer no CSS é alinhar verticalmente elementos em tela. Existem várias formas de fazer isso. Neste post, vou elencar as minhas formas favoritas de fazer isso.

    Alinhamento com Flexbox

    Flex é uma propriedade incrível do CSS que permite organizar elementos. Se outrora tínhamos que fazer inúmeras gambiarras com float, o flex nos permite controlar o comportamentos dos filhos de um container. Para centralizar verticalmente um objeto, podemos usar a direção de coluna, em seu container pai.

    Alinhamento com position

    Com um pouco de matemática, conseguimos fazer um alinhamento vertical com o position absolute. Porém, é importante lembrar que o objeto será flutuante e que seu pai, necessariamente, precisa ser um position relative. O problema de usar esse tipo de alinhamento é que o conteúdo da posição precisa ser fixo. Felizmente, hoje, conseguimos fazer cálculos com variáveis de CSS, o que facilita a forma de implementarmos essa técnica. A vantagem dessa técnica é poder usar, justamente, em ambientes flutuantes que se sobreponham. Porém, caso você não precise que ele se alinhe ao pai, mas à viewport, você pode usar também o position como fixed.

    Alinhamento com Grid

    Outra forma moderna de alinhar verticalmente é através do uso de grids. A vantagem de usar grids é que o tamanho do conteúdo do elemento alinhado corresponderá ao tamanho da grid que se deseja utilizar. Ou seja, é adaptável de acordo com a viewport, e não referente ao seu conteúdo. Para isso, basta definirmos a quantidade de colunas e linhas que desejamos e estabelecemos onde o objeto alinhado vai iniciar e terminar.

    Exemplo de uso (Modal Alinhado ao Centro)

    Para mostrar como pode ser usado os alinhamentos, que tal criarmos um simples modal alinhado ao centro da tela?

    Um modal é composto por uma cortina que reveste o conteúdo original, seguido de um painel com alguma informação dentro. É convenção de que os modals carreguem essas informações no centro da tela, afim de que a informação fique direcionada e encapsulada, levando, assim, o usuário à uma atenção maior àquela informação. Ou seja, isolar e destacar. O exemplo abaixo foi feito usando a primeira estratégia de alinhamento vertical aqui apresentada, pois, desta forma, o tamanho do modal que vai ser a referência para a centralização. Alguns efeitos foram adicionados para ilustrar melhor.

  • Como adicionar e remover dinamicamente campos HTML em um Formulário? (Javascript puro)

    Como adicionar e remover dinamicamente campos HTML em um Formulário? (Javascript puro)

    O Javascript nos permite criar conteúdos dinâmicos e podemos usar isso para adicionar remover e adicionar elementos de acordo com as opções do usuário. Dados como informações sobre dependentes, links de mídias sociais, e-mails adicionais, etc. são curtos e não fazem sentido criarmos um formulário separado apenas para estes. Por isso, é interessante incluirmos a opção de adicionar diretamente esses campos em um subformulário dinâmico.

    Obs. Se quiser ir direto para o código final, procure o link do JsFiddle no final do post.

      
    

    HTML

    Para iniciarmos, basta criar um container no HTML onde você quer que os elementos sejam exibidos, além do botão simples de adição e um botão de captura de dados, para que, desta forma, possamos enviar o JSON resultante para o back-end.

    A organização dos containers é sempre muito importante quando trabalhamos com Javascript e nos dedicamos ao uso correto da web semântica.

    Javascript

    Como de praxe, usaremos o Javascript puro para realizar essa tarefa, dessa forma você poderá usar em qualquer lugar o que aprender aqui.

    Para poder capturar e devolver os dados, usaremos um objeto JSON, dessa forma fica fácil remontar, tanto no back-end, quando no front-end, os dados nas formatações e/ou elementos que precisamos.

    Vamos criar, como exemplo, o JSON abaixo, e vamos declará-lo em uma variável global chamada dependentes, seguindo a ideia de um cadastro de lista de dependentes, então temos:

    Agora vamos nos focar nas funções. A primeira coisa que vamos fazer é criar um método que pegue os dados do JSON e o converta para elementos HTML renderizados na tela. Dessa forma, usaremos um laço para ler o JSON e aplicamos seus dados em uma template string e o adicionamos no container específico:

    Agora vem o segredo que facilita o processo e o deixa mais organizado. Ao invés de remover e adicionar os elementos na tela, iremos nos focar em remover e adicionar do JSON e, em seguida, regenerar os elementos a partir desse objeto. Ficando, assim, com um código mais limpo. Outro motivo pelo qual usamos a regeneração dos elementos é para evitar criarmos IDs únicos temporários. Ao regenerar, podemos usar os índices do próprio array como identificador.

    Para adicionar um novo item, basta incluirmos um dado vazio no JSON, porém, seguindo nosso modelo, e mandamos gerar novamente os elementos:

    Para remover, similar a criação de um novo, vamos usar um laço, porém para adicionar o evento aos botões de excluir. Usaremos então o método splice para remover o array. Depois, obviamente, vamos regenerar os elementos a partir da função carregarDependentes():

    Uma vez que adicionamos uma nova linha em branco precisamos salvar seu preenchimento e aí iremos usar a mesma lógica de remoção, mas usaremos o splice para substituir e não para remover um dado do JSON. Porém, adicionaremos uma pequena validação para evitar entrar dados incompletos:

    Um outro método que precisamos adicionar é uma forma de bloquear para que um usuário consiga clicar em outros elementos ao redor, sem antes finalizar a edição do item. Para isso, iremos fazer um laço que adiciona uma classe de CSS, que vamos chamar de disabled, em todos os elementos, exceto o que está sendo editado. Essa classe possui um point-events: 0 e um opacity: 0.5. Para demonstrar que está desativado, você pode ainda adicionar outros efeitos, como filtros de baixo contraste ou escala de cinza.

    Agora, antes de continuarmos, vamos revisitar as funções acima para chamar, quando necessário, uma função dentro da outra (leia os comentários no código para entender), ficando assim:

    Agora, tudo o que precisamos fazer é incluir os comandos de inicialização, onde aplicamos o método de adição ao evento de clique do botão e carregamos os dados iniciais do JSON:

    Por fim, vamos criar uma função para o botão de capturar dados apenas para extrair e mostrar os dados em JSON. Você pode, eventualmente, usar esses dados e enviar via POST, por AJAX ou via campo oculto, e pegar no back-end para guardar ou processar os dados (como com um json_decoder, do PHP):

    CSS

    O único CSS que precisaremos usar é para aplicar a classe disabled. Se por acaso você está usando algum framework CSS, recomendo que você use o relativo a esta classe deste. Consulte a documentação, onde geralmente está relacionado aos helpers:

    Se você quer usar o CSS mais elaborado que usei aqui, veja abaixo o link do JsFiddle.

    Finalizando

    Criar formulários dinâmicos auxilia a usabilidade à medida que permite que o usuário adicione dados de forma mais rápida e com respostas visuais imediatas. O uso aqui do Javascript puro visa a facilidade para que você possa implementar em quaisquer projetos, incluindo os com Typescript. Trabalhe um pouco no código para adequá-lo à sua necessidade. E, como sempre, você poderá puxar o código e testar direto do JsFiddle.

    Aproveite e entre para nosso grupo de discussão no Telegram.

  • Como criar um uploader drag & drop, AJAX com porcentagem e Javascript puro?

    Como criar um uploader drag & drop, AJAX com porcentagem e Javascript puro?

    Eu sei, o título é grande, mas trata-se de uma tecnologia muito útil quanto a usabilidade. A ideia é criar, da forma mais simples possível um uploader que mostre a porcentagem do que está sendo enviado, com múltiplos arquivos. Porém, não apenas isso, mas da forma mais pura possível, sem a necessidade de frameworks, bibliotecas de terceiros ou pre-processadores. Em nosso tutorial, usaremos PHP no back-end, mas você pode usar a linguagem que melhor lhe adequar. Abaixo você pode testar um exemplo:

    DISCLAIMER: Para preservar você, o blog e a mim, o upload.php do exemplo não está fazendo upload de verdade, então você não vai ter acesso ao arquivo no final, porém, no link do github está o código funcional.

    Download

    HTML

    Antes de prosseguir, vou alertar que estou usando o font-awesome no exemplo, apenas para não ter que fazer nenhum upload de imagens por hora, mas ele não é obrigado para o que vamos fazer.

    Iniciaremos com um HTML bem simples. Vamos definir apenas a área de upload, da lista e uma área onde ficará o input. Esse input deve ser do tipo file e deve estar com o atributo mutiple definido. Nada muito especial por enquanto, pois nosso trunfo está mais no CSS e Javascript.

    CSS3

    O CSS que usaremos tem pontos específicos aos quais devemos prestar atenção. Por isso, vamos ver por trechos:

    A área de upload é definida pelo CSS a partir de um espaço abrangente. O label, vai ser a referência que vamos usar para atingir toda a área pré-determinada e é o que vai também receber o estilo que indicará onde e quando pode soltar o objeto. Dessa forma, deve estar com um position: absolute, pegando toda a área do upload. Um detalhe importante é que esse label não pode possuir filhos com eventos do mouse, pois isso pode acarretar em funcionamento inadequado ao fazer um hover em uma área não indicada.

    A área marcada como hightlight é justamente para demonstrar ao usuário que ele já pode soltar o arquivo.

    O input vai nos servir de área de drop. Isso já é um padrão tanto para Windows, MacOS e Linux – de receber um (ou mais arquivos) arrastando os dados para o botão. Retirando a aparência padrão, podemos nos aproveitar dessa função e economizar várias linhas de código do Javascript. Não havendo a necessidade de configurarmos eventos de arquivos.

    Talvez a área que possa confundir um pouco mais, principalmente os mais novatos, seja o CSS referente as barras de loading. As barras são definidas como relative e seu conteúdo como absolute. Dessa forma, podemos herdar a porcentagem do upload e usá-la diretamente no min-width do elemento. Usamos min-width, ao invés de width para utilizar o transition, dando uma leveza no upload ao invés de pequenos estalos.

    Javascript

    Inicialmente iremos definir os efeitos de drag and drop. Utilizaremos os eventos específicos para adicionar ou retirar o css de hightlight. Aquele que falamos acima ao montar o CSS.

    Agora precisamos validar os dados antes de colocar em nosso servidor. Compusemos uma validação que verifica o tipo de arquivo e a quantidade máxima de 2MB. Essa validação é totalmente no front-end. É recomendado que você também faça uma validação posterior no back-end para evitar fraudes. Essa função receberá como parâmetro um arquivo, o qual faremos a validação.

    Para enviar os arquivos, usaremos uma função AJAX simples. Fazemos um request no método POST. Nesta função, iremos capturar também a porcentagem do upload e atualizaremos a barra a partir desta, através do evento progress. Essa nossa função receberá o índice, para identificar o arquivo que está sendo enviado e a barra que será modificada.

    Por fim, iremos juntar um pouco de cada coisa que fizemos, adicionando uma função em um evento change do input do upload. Neste momento, também é feito o laço dentre o(s) arquivo(s) selecionado(s) para validar e, se for válido, fazer o upload, utilizando os outros métodos acima mencionados. É neste momento também que serão criadas dinamicamente as barras: uma para cada arquivo.

    PHP

    E pra terminar com chave de ouro, um PHPzinho que receberá esses arquivos e retornará um json com a confirmação de sucesso ou erro. Não aplicamos muitas validações nesse PHP pois nosso foco era neste exemplo está no front-end, mas é suficiente para que você compreenda sua funcionalidade.

    E, como sempre, você pode baixar o código inteiro no Github e usar direto na sua aplicação.

    Download

    Gostou? Se sim, compartilha com seus amiguinhos interessados na área e curte a página no Facebook. O exemplo acima está levemente modificado para que funcione melhor aqui no site. Entre também no grupo de Design e Desenvolvimento. O link está abaixo do post.

  • Como fazer efeito float label animado com CSS3 puro

    Como fazer efeito float label animado com CSS3 puro

    O último post sobre como criar um efeito ON/OFF em um checkbox usando CSS3 puro fez muito sucesso. Dessa forma, pensei o que mais poderia ser legal para fazer com CSS3. Analisando um pouco o comportamento do Android, me lembrei de um componente bem interessante que é o input com um label float animado. Basicamente, ao preencher o conteúdo, o label sobe e vai para um pouco acima do input, como no exemplo abaixo:


    Agora… como fazer?

    O segredo está novamente nas pseudoclasses e operadores. Graças as pseudoclasses eu posso definir, com alguns gatilhos, o comportamento de um determinado elemento HTML.

    No caso, esse gatilho é o placeholder, então é fundamental que o input possua um placeholder (vazio ou não) para criar o efeito. Pois o que identifica que algo foi preenchido ou não é justamente o placeholder. Sem o placeholder definido, o efeito não funciona. A pseudoclasse referente ao required também é usada em nosso exemplo:

    Já para o efeito de transição, usaremos o transition e o comportamento do absolute que, por definição, tem seus eixos referentes ao pai, no caso desse ser relative. Então basta usar o CSS abaixo:

    Como sempre, estou disponibilizando o exemplo completo no JsFiddle!

    Gostou? Então curta a página no Facebook e compartilhe com os coleguinhas!

  • Destacando um Elemento HTML (coachmark): Efeito Spotlight ( com CSS3 e Javascript puro)

    Destacando um Elemento HTML (coachmark): Efeito Spotlight ( com CSS3 e Javascript puro)

    Obs. Se você só quer o código pronto, pule para o final do post. Ou acesse o link do JSFiddle.

    As vezes precisamos encontrar formas de destacar elementos na tela (coachmark). Isso é muito útil principalmente quando você está tratando de pequenos tutoriais, afim de ajudar os usuários. Convém, também, entregar soluções simples e esteticamente elegantes para que ajudem no relacionamento com a ferramenta.

    Faz algum tempo, um cliente meu quis criar um modo tutorial em seu sistema. Esse tutorial não deveria permitir que outras áreas da tela fossem clicadas até que a pessoa confirmasse que compreendeu. Como designer, lembrei que, anos atrás, no Android, a Google usava uma espécie de spotlight, mas não vi nada a respeito para websites. E, também, eu precisava que fosse dinâmico. Então eu resolvi usar meus conhecimentos de CSS3 e Javascript para usar essa ideia. E é disso que eu falarei neste tutorial.

    Apesar de eu ter usado originalmente jQuery, para compartilhar com todos, resolvi fazer uma versão com Javascript puro, de forma que você poderá adicionar a qualquer aplicação web que você já tenha.

    Criando a Estrutura: HTML e o CSS3

    Para criar o efeito, vamos usar uma propriedade interessante do CSS3 chamada clip-path. O clip-path permite que criemos elementos vetoriais que serão usados como máscaras. Já utilizamos essa propriedade em um outro exemplo, no caso, sobre um loader.

    Exemplo de uso do clip-path:

    Dessa forma, se já não tiver, teu projeto deve possuir um container principal que é pai de todos os elementos, mas abaixo do <body>. Se não houver, o crie, é até uma questão lógica de organização para evitar problemas futuros. Veja um código de exemplo:

    A div container vai ser justamente o elemento que iremos clippar. Para ajudar em nosso exemplo, vamos criar um form básico dentro do container, ficando assim:

    Para finalizar nosso HTML, vamos colocar a caixa de mensagens. Repare que no código abaixo a caixa de mensagem vai ter uma div chamada spacer. O objetivo dessa div vai ser adicionar o espaço do elemento referência, para que o código funcione também em dispositivos móveis e ela deverá ficar fora do container da aplicação. Mais à frente isso vai ficar mais bem explicado.

    Agora que o HTML está pronto, vamos para o CSS inicial. A primeira fase é estabelecer todo comportamento da div que estamos usando como container. Também precisamos adicionar uma cor ao plano de fundo, que vai ser a cor que usaremos como base para a área em lowlight.

    A animação ficará a cargo do recurso transition do CSS3. Importante ressaltar que uma animação criada por CSS é mais leve e possui melhor frequência do que uma criada pelo Javascript. Isso porque o navegador tenta usar a renderização da GPU nesses casos. Dessa forma, vamos aplicar o parâmetro transition para aplicar o efeito.

    O parâmetro position como absolute, com suas larguras e alturas mínimas marcados como 100% servirão para emular o comportamento do body. Isso só é necessário porque alguns sistemas costumam ter áreas menores do que a primeira dobra do navegador. Nesse caso, apenas, é necessário aplicar esses três parâmetros.

    Já para o CSS do bloco de mensagem, você pode fazer algo do jeito que preferir. Apenas é importante lembrar que esse bloco deverá ficar com position absolute, ou fixed, dependendo de como for sua aplicação, para que possa se encaixar no local correto.

    Criando as Funções Javascript

     Agora basta que a gente crie as funções de aparecer e desaparecer o spotlight. Originalmente eu havia usado jQuery, pois ele possui soluções rápidas e funcionais como o offset nativo e outerWidth, mas com uma pesquisa rápida conseguir adaptar, apesar do código ter ficado um pouquinho maior.

    O código consiste em 4 blocos:

    • Capturar largura e posição em relação ao document, do objeto referência (que será passado como parâmetro), fazendo os cálculos apropriados para adição do círculo. Você irá reparar que é usado como base o raio e não o diâmetro, pois é a referência do parâmetro clip-path;
    • Adicionar o clip ao container;
    • Adicionar os textos da mensagem a partir dos parâmetros passados;
    • Aplicar os estilos com os novos parâmetros. O timeout que precede a adição da classe show da mensagem existe para que o texto apareça após a transição do spotlight.

    Por fim, basta adicionar uma função que restaure as configurações originais dos estilos e textos.

    Como sempre, deixei o código completo para você testar ou copiar. No caso, o código está no jsfiddle e você pode visualizar abaixo:

    Se você gostou da publicação, curta e compartilhe esta página com o maior número de pessoas. Aproveite e curta nossa página do Facebook.

    ATUALIZAÇÃO: Que tal experimentar uma versão com blur, usando o html2canvas? Obs. É meio pesado. Dê preferência a usar em projetos para desktop.

  • Exemplo de App Ionic – Hackathon

    Exemplo de App Ionic – Hackathon

    Disclaimer: O objetivo deste post é tão simplesmente compartilhar o projeto que possa ser útil para alguém que está precisando ou quer aprender um pouco de Ionic. É um projeto feito em poucas horas, durante um hackathon, então não espere pelas melhores práticas. Para dúvidas mais complexas, entre em nosso grupo de Design e Programação, no Facebook.


    Veja o projeto no Github:

    Star

    No último final de semana (29 e 30 de Setembro de 2018), participei do Hackathon do Shopping Center Recife. Devido a um erro da desorganização, acabei ficando em um grupo que não haviam outras pessoas que tivessem ao menos noção de programação (enquanto havia grupo composto inteiro por pessoas que sabiam programar), de forma que acabei programando sozinho durante cerca de 20 horas. Por outro lado, o restante do meu time conseguiu me auxiliar fazendo a apresentação e com uma ideia que poderá ser muito valiosa para o projeto de algumas pessoas, que irei explicar abaixo.

    Equipe, da esquerda para a direita: Eu, Marcos Lemos, Pedro Affonso, Suellen Sales e Helton Portela

    O projeto

    Diferente do que foi referido pelo edital do Shopping, que afirmava buscar uma solução de “relacionamento com o cliente”, o objetivo principal era encontrar uma forma de conseguir dados mais assertivos sem a necessidade direta de contatos com o lojista. Esses dados seriam analisados e entregues de forma a ajudar o Shopping a criar novas campanhas. Tudo sem diminuir faturamento.

    Para isso, eu pensei que poderia desenvolver uma versão do aplicativo do Shopping, que já existe, e melhorar, otimizar, deixa-lo mais fluido e com mais opções. Inicialmente, pensei em integrar o Google Indoors, mas GPS não funciona corretamente no Shopping e o Indoors não está disponível por um tempo limitado. Algumas equipes até sugeriram algo parecido, na entrega, mas apenas sugestão, pois seria inviável descobrir a localização atual em ambiente tão contido apenas por triangulação. Enfim, pensei em envolver compartilhamento em mídia social também, para engajamento, etc.

    No final, o projeto consistiu em uma nova versão do aplicativo, com um chatbot amigável, um clube de vantagens que armazena informações da nota fiscal (pelo QRCode) e a proposta de manipulação desses dados no backoffice, além de campanhas direcionadas pelo mesmo. Alguns dos outros grupos usaram propostas bem similares.

    No fim, eu decidi que o principal seria apresentar os dados em um backoffice. Minha ideia inicial era realmente preparar um BI, ou o começo do que poderia ser um, usando os dados do aplicativo reformulado. Porém, os outros integrantes de minha equipe tiveram a ideia de criar um clube de vantagens que pegasse o código do QRCode do cliente, pegando assim dados bem mais específicos sem a necessidade de acordos com o lojista, em trocas de pontos que poderiam ser trocados por serviços do shopping ou de parceiros mais próximos (como o cinema), que admito ser melhor que a minha ideia original.

    Se por um lado, eu decidi fazer algo que pudesse se tornar um BI (Business Intelligence), por outro, o tempo não foi favorável. Sendo o único desenvolvedor, eu fui obrigado a dividir meu tempo entre aplicativo, backoffice e banco. Logo, não esperem um código tão bem escrito. Lembre-se que é um projeto desenvolvido do zero em algumas poucas horas.

    Tecnologias

    Para agilizar o desenvolvimento e ainda poder ser algo demonstrável em tempo real direto no navegador (para exibir no telão), o projeto do app foi feito em Ionic 3, famoso framework Cordova para desenvolvimento de aplicações em vários dispositivos. Graças a isso, ainda conseguia testar em tempo real no Android e no iOS. Fiz o possível para implementar o máximo de funcionalidades possíveis.

    Para o backoffice, entretanto, por questão principalmente de tempo, apostei no PHP e MySQL, não pela experiência em si, apesar de conhecer bem a linguagem, mas porque eu poderia simplesmente usar meu servidor de site comum e não ter que configurar um ambiente. Dessa forma, perdi menos tempo. Mesmo assim, só consegui fazer 20% do que eu planejei para essa parte.

    Ionic

    Usei e abusei da interface padrão, com poucas modificações e atualizações, observando sempre a documentação quanto ao uso dos componentes. Aqui cabe um outro disclaimer: apesar de já trabalhar há cerca de um ano com Phonegap/Cordova e já ter feito algumas brincadeiras nele, estou mexendo no Ionic há apenas duas semanas, então perdoe-me se eu estou usando alguma má prática em seu código (ao menos os nomes das páginas eu já adianto que estão bagunçadas).

    Sabrina – A Chatbot

    Sabrina foi o nome escolhido para a chatbot. Por quê? Sei lá, veio na cabeça. Basicamente ela usa Watson para poder realizar a conversa. Com algumas poucas diferenças, caso você queira saber mais como funciona essa parte de chatbot, consulte o outro artigo onde eu explico como criar um chatbot simples usando a ferramenta da IBM. Ainda resolvemos dar uma identidade para e os outros membros da equipe a treinaram para responder perguntas de forma a convidar as pessoas que não estão no shopping e ainda sugerir lojas em caso de perguntas menos específicas.

    Obs. Abaixo, vai ter uma área de testes. Se você for testar em nosso site, lembre-se que usamos o plano de 30 dias grátis, então dependendo da data que você ler este artigo pode não funcionar. Também só tivemos tempo para responder uma série limitada de perguntas. E não treinamos a conversação mais complexa (apesar de que você vai encontrar no código trechos que mostra que estava sendo desenvolvido).

    Sabrina Chatbot Watson

    Clube de Vantagens

    A parte do clube de vantagens visava o login fácil pelo Facebook (está implementado em beta no código, mas comentado, pois só funciona compilado). Através disso, pegaria o máximo de informações públicas possíveis, para entender os gostos do cliente. Claro que estou ciente que as novas políticas do Facebook exigem uma aprovação, mas isso não seria problemas para um dos maiores shoppings do Brasil.

    Após esse login, entraria a opção de ver suas informações, compartilhar com amigos, através de um código promocional (que dá pontos), e que ainda daria alguns feedbacks gráficos para estimular uma ludificação. Os valores dados seriam sempre grandes, na margem mínima de 100 pontos para compras menores e 500 pontos para compras maiores. Essa quantidade foi pensado do ponto de vista de marketing, pois pontos maiores dão a sensação de que o retorno é maior, mesmo que a exigência para a conversão em um serviço ou produto fique na casa das dezenas dos milhares.

    QR Code e NFCe

    Por outro lado, havia a necessidade de ler o QRCode e acessar os dados de uma NFCe sem um certificado digital. O maior problema que enfrentamos é: como fazer isso através do servidor, se as Sefaz bloqueiam o cross-origin (ao menos a Sefaz de Pernambuco), retornando o erro “Cross-Origin Read Blocking (CORB) blocked cross-origin response“? Percebi que os outros grupos que envernizaram por esse lado tiveram esse problema e, até onde eu vi os códigos, ninguém realmente resolveu o problema. Então, me atentei que eu simplesmente poderia “enganar” o site da Sefaz para acreditar que eu na verdade sou um usuário direto do navegador. Como? Simplesmente declarando um cabeçalho como Firefox! O trecho fica assim (PHP):

    Obs. Eu não testei com NFCe de outros estados.

    O resultado foi exatamente a XML da NFCe. E como entender e ler? Bem, para isso basta usar o DOM Document, mas se você quiser entender mais sobre como funciona esse processo de nota fiscal eletrônica, leia o artigo que eu escrevi anteriormente sobre o assunto.

    Já o QRCode, o próprio Ionic tem uma solução para isso, e foi implementada, mas me deparei com um problema: Só funcionava corretamente no Android e iOS e eu precisava apresentar tudo no navegador. A solução? Encontrei uma biblioteca de Javascript puro que fazia a leitura do QRCode pela webcam. Então tive que aprender como integrar Javascript puro a um projeto Ionic. Nem foi tão difícil, está compreensível se você olhar a página do QRCode no projeto. O único problema é que a webcam não tem autofoco, então há uma margem curta para que seja lido corretamente o QRCode. Por conta disso, no navegador, pela webcam, eu só consegui ler os QRCodes que estavam sem amassados e bem nítidos. Aliás, testamos uma nota emitida em contingência e, por algum motivo, a URL do QRCode retornava chave inexistente (?).

    Após ser lido, o QRCode retorna uma mensagem com o a pontuação que você efetivamente fez, e retorna também o valor da nota. Ainda envia os detalhes da nota para o backoffice.

    Backoffice

    O backoffice captura os dados e exibe para o usuário. No projeto, os gráficos que estão mostrados no dashboard não são reais, foram colocados manualmente, mas os que mostra as vendas é atualizado em tempo real assim que a pessoa coloca o QRCode. Os nomes dos compradores estão censurados no front, eu sei que deveria ser no back (aliás, já armazenado sem o nome), mas não tive tempo de pensar em segurança e já era 3 da manhã no momento que eu comecei a implementar isso.

    Por conta disso, eu não tive como implementar tudo o que eu queria, de forma que tem mais exemplos do que efetivado.

    O meu intuito era usar todos os dados capturados, inclusive o retorno da Sabrina (a chatbot) para criar índices de relevância de 0 a 100. Exemplo:

    1. João, identificado como usuário J72, perguntou sobre compras de sapato a Sabrina, isso dá 1 ponto na subcategoria calçados para J72, pela intenção de compra.
    2. Se J72 efetivamente comprar o sapato, ele receberá 2 pontos na subcategoria calçados, pela compra realizada.
    3. O cruzamento entre a intenção e compra realizada dá ainda mais 3 pontos, na subcategoria calçados.
    4. Ao todo o processo do usuário J72 resultaria em 5 pontos de relevância para o usuário J72, que seria somado aos seus outros pontos, caso já tivesse.
    5. Quando atingir 70 pontos, na subcategoria calçados, esta será considerada como categoria de relevância para o usuário J72.

    Com isso, a home, mostrada para o usuário J72 seria organizado de acordo com seus índices personalizados e campanhas direcionadas, direto pelo aplicativo e também por notificações, poderiam ser enviadas para os usuários do aplicativo, de acordo com suas relevâncias. Além de, claro, o resultado do acompanhamento dessa campanha.

    Exemplo de como funcionaria a criação de campanha direcionada

    Além disso, esses dados deveriam ser cruzados para sugerir a equipe de marketing, as melhores estratégias de acordo com o comportamento do grupo e em quais mídias seriam mais adequadas para investir em propaganda. Infelizmente, essa foi a parte que não deu tempo de desenvolver, pelos motivos supracitados. Mas, essa imagem, desenvolvida por outros membros da equipe, ajuda a ilustrar a lógica que seria aplicada para a criação do algoritmo. Vale lembrar que, as informações do Facebook, vinculados ao comportamento de compra, ajudaria e as conversas com a Sabrina e as bases de dados que o Shopping já possui, ajudariam a definir o comportamento do público.

    Finalizando

    Disponibilizei todo código desenvolvido, do backoffice e do projeto Ionic no Github, para caso você deseje experimentar ou apenas dar um olhada no código. Mas lembre-se que não vou fazer manutenção de nada, é apenas um exemplo para estudo:

    Star

    Entretanto, se você quiser apenas ver, testar o que foi demonstrado, você pode acessar o backoffice aqui, ou o aplicativo aqui. Caso abra o aplicativo em um desktop ou laptop, recomendo que você use o modo de device toolbar do Google Chome para visualizar corretamente -> Para isso, pressione CTRL+SHIFT+i (substitua ctrl, por command, no Mac) e clique no segundo ícone do canto superior esquerdo do console. Ou simplesmente veja o vídeo abaixo:

    Por que não vencemos? Talvez por não ter tanto tempo para explicar o projeto, talvez por não ter encontrado uma boa forma de demonstrar, ou simplesmente porque não é realmente tão interessante. Mas, de qualquer forma, rendeu um post para o blog, para o qual pode ser útil para alguém que esteja aprendendo Ionic ou qualquer outro tema aqui relacionado. Lembre-se de entrar no grupo do Facebook para tirar mais dúvidas.

    Obrigado para você que leu até aqui e obrigado a equipe que foi integrante desse projeto. Me siga no Twitter e Instagram e deixe seu like no Facebook.

  • Como Selecionar o Item de Uma Tabela HTML

    Como Selecionar o Item de Uma Tabela HTML

    Uma dúvida foi postada no grupo de Design e Programação de nossa página, lá no Facebook, hoje. Essa pergunta era referente a como selecionar de uma linha de uma tabela HTML?

    Para tal, basta usar um pouco de Javascript e CSS.

    Montando a Tabela

    Vamos montar, para testar, uma tabela simples, respeitando a semântica HTML básica. Vamos aproveitar para colocar logo um botão, que vai ser por onde podemos visualizar os dados da linha selecionada:

    <table id='minhaTabela'>
         <thead>
              <tr>
                   <th>ID</th>
                   <th>Nome</th>
                   <th>Idade</th>
              <tr>
         </thead>
         <tbody>
              <tr>
                   <td>01</td>
                   <td>Rodrigo</td>
                   <td>33</td>
                   </tr>
              <tr>
                   <td>02</td>
                   <td>Taynara</td>
                   <td>21</td>
              </tr>
              <tr>
                   <td>03</td>
                   <td>Raveny</td>
                   <td>22</td>
              </tr>
              <tr>
                   <td>04</td>
                   <td>Sérgio</td>
                   <td>51</td>
              </tr>
              <tr>
                   <td>05</td>
                   <td>Alice</td>
                   <td>20</td>
              </tr>
         </tbody>
    </table>
    
    <button id="visualizarDados">Visualizar Dados</button>
    

    Agora precisamos incluir um estilo para que a tabela fique mais elegante.

    É importantíssimo prestar atenção ao class “selecionado” que vai ser a referência para o seu javascript saber qual linha está selecionada na tabela.

    #minhaTabela{
      width:80%;
      margin:0 auto;
      border:0;
      box-shadow: 0 5px 30px darkgrey;
      border-spacing: 0;
    }
    
    #minhaTabela thead th{
      font-weight: bold;
      background-color: black;
      color:white;
      
      padding:5px 10px;
    }
    
    #minhaTabela tr td{
      padding:5px 10px;
      text-align: center;
      
      cursor: pointer; /**importante para não mostrar cursor de texto**/
    }
    
    #minhaTabela tr td:last-child{
      text-align: right;
    }
    
    /**Cores**/
    #minhaTabela tr:nth-child(odd){
      background-color: #eee;
    }
    
    /**Cor quando passar por cima**/
    #minhaTabela tr:hover td{
      background-color: #feffb7;
    }
    
    /**Cor quando selecionado**/
    #minhaTabela tr.selecionado td{
      background-color: #aff7ff;
    }
    
    button#visualizarDados{
      background-color: white;
      border: 1px solid black;
      width:50%;
      margin: 10px auto;
      padding:10px 0;
      display: block;
      color: black;
    }
    

    Javascript

    Para sermos mais justos, vamos fazer o exemplo usando Javascript puro. No nosso exemplo, vamos contemplar a opção de selecionar uma única linha ou mais de uma linha, opção determinada apenas por um parâmetro. Ainda vamos ver como manipular os dados.

    Inicialmente, precisamos capturar a tabela e adicionar, à ação de clique, uma função que adicione ou remova a classe de seleção:

    var tabela = document.getElementById("minhaTabela");
    var linhas = tabela.getElementsByTagName("tr");
    
    for(var i = 0; i < linhas.length; i++){
    	var linha = linhas[i];
      linha.addEventListener("click", function(){
      	//Adicionar ao atual
    		selLinha(this, false); //Selecione apenas um
                    //selLinha(this, true); //Selecione quantos quiser
    	});
    }
    

    A função selLinha() vai ser responsável por adicionar ou remover a class “selecionado” do nó. Passamos também um parâmetro que vai determinar se poderá selecionar mais que uma linha ou apenas uma. O primeiro laço, caso múltiplos seja falso, irá apenas desmarcar todos as linhas antes de marcar a linha clicada.

    /**
    Caso passe true, você pode selecionar multiplas linhas.
    Caso passe false, você só pode selecionar uma linha por vez.
    **/
    function selLinha(linha, multiplos){
      if(!multiplos){
      	var linhas = linha.parentElement.getElementsByTagName("tr");
            for(var i = 0; i < linhas.length; i++){
               var linha_ = linhas[i];
               linha_.classList.remove("selecionado");    
            }
      }
      linha.classList.toggle("selecionado");
    }
    

    Agora vamos adicionar uma função ao clique do botão para que a gente possa visualizar os dados selecionados. Para isso, iremos justamente capturar apenas as linhas que tiverem a class “selecionado” e, através de um laço, vamos concatenar os valores dentro dos nós <td> da(s) linha(s) selecionada(s).

    /**
    Exemplo de como capturar os dados
    **/
    var btnVisualizar = document.getElementById("visualizarDados");
    
    btnVisualizar.addEventListener("click", function(){
    	var selecionados = tabela.getElementsByClassName("selecionado");
      //Verificar se eestá selecionado
      if(selecionados.length < 1){
      	alert("Selecione pelo menos uma linha");
        return false;
      }
      
      var dados = "";
      
      for(var i = 0; i < selecionados.length; i++){
      	var selecionado = selecionados[i];
        selecionado = selecionado.getElementsByTagName("td");
        dados += "ID: " + selecionado[0].innerHTML + " - Nome: " + selecionado[1].innerHTML + " - Idade: " + selecionado[2].innerHTML + "\n";
      }
      
      alert(dados);
    });
    

    Vamos Testar?

    ID Nome Idade
    01 Rodrigo 33
    02 Taynara 21
    03 Raveny 22
    04 Sérgio 51
    05 Alice 20

    No entanto, se você preferir ver todo código completo, acesse o JsFiddle incorporado abaixo:


    Gostou do post curtinho? Tem dúvidas? Deixe seu comentário e compartilhe com quem você achar que vai gostar. Aproveite para entrar no nosso grupo de Design e Programação no Facebook ou em nossa página. Acompanhe-nos no Twitter e Instagram.

  • Gráfico / Loader Radial com CSS e Javascript Puro

    Gráfico / Loader Radial com CSS e Javascript Puro

    Disclaimer: If you are coming from an english or international chat/group, please roll to jsfiddle at the end of this post and get all comments and explanations in english or access jsfiddle link.

    Bibliotecas de gráficos existem aos montes. A maioria pesada e com poucas (ou complexas) opções de personalização. De modo que, pensei, será que é possível usar a animação do CSS para criar um gráfico leve? Como exercício, talvez eu pudesse desenvolver uma solução de gráfico radial que pudesse funcionar bem. Esse questionamento veio a partir da pergunta de uma pessoa, em um grupo, que queria criar um loading infinito com CSS.

    Criando o CSS

    Para poder criar a animação do load, pensei em diversas formas que já são usadas como solução, como o gradient ou gambiarras com contornos, mas eles não usam realmente o conceito da animação do raio a partir do centro. Para resolver, pensei em apelar para a trigonometria. Dividi então o círculo em 4 triângulos retângulos.


    A partir daí podemos considerar a animação a partir de cada dos vértices da hipotenusa, se abrindo do raio, formando o triângulo retângulo, como no exemplo abaixo:

    <style>
     .triangulo{
        width: 200px;
        height: 200px;
        background-color: #c1f347;
        margin:0 auto;
        animation: triangle 3s infinite  alternate;
    }
    
    @keyframes triangle {
        from   {
            clip-path: polygon(50% 0%, 0% 100%, 0 100%);
        }
        to {
            clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
        }
    }
    <style>

    OK, conseguimos criar os triângulos com o clip-path do CSS. Graças ao ele podemos colocar caminhos de uma imagem a partir de vértices. Mas como colocar isso nos 4 triângulos? Não faria o menor sentido colocar os triângulos um do lado do outro. Como fazer então para utilizar um caminho completo para dar o efeito de transição radial?

    Para isso, basta fazermos um cálculo simples. Quantos vértices seriam necessários para criar um polígono que dê a volta? Bem, basta contarmos o vértices do quadrado (4) mais um ao centro que define os triângulos e mais um para fechar a animação. Ou seja, precisamos de um hexagono.

    <style>
     .hexagono{
         width: 250px;
         height: 250px;
         background-color: #f98b2a;
         margin: 0 auto;
         animation: hexagon 3s infinite  alternate;
    }
    
    @keyframes hexagon {
         from   {
              clip-path: polygon(50% 0%, 90% 20%, 100% 60%, 75% 100%, 25% 100%, 0% 60%, 10% 20%);
              background-color: #2af9f7;
         }
        to {
              clip-path: polygon(50% 0%, 100% 0, 100% 60%, 100% 100%, 0 100%, 0% 60%, 0 0);
         }
    }
    <style>

    Agora basta manipular os vértices do hexagono para se comportar similar ao triângulo retângulo, levando os pontos do vértice, em fila, sempre ao próximo ponto do quadrado.

    <style>
     .quadrado{
        width: 250px;
        height: 250px;
        background-color: #f98b2a;
        margin:0 auto;
        animation: square 3s infinite  alternate;
    }
    
    @keyframes square {
        0%   {
            clip-path: polygon(100% 0, 100% 0%, 100% 0%, 100% 0%, 100% 0%, 50% 50%);
            background-color: #36ff9a;
        }
        25%  {
            clip-path: polygon(100% 0, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 50% 50%);
            background-color: #fccf40;
        }
        50%{
            clip-path: polygon(100% 0, 100% 100%, 0% 100%, 0% 100%, 0 100%, 50% 50%);
            background-color: #f40696;
        }
        75%  {
            clip-path: polygon(100% 0, 100% 100%, 0 100%, 0 0%, 0 0, 50% 50%);
            background-color: #55aadd;
        }
        100% {
            clip-path: polygon(100% 0, 100% 100%, 0 100%, 0 0, 100% 0, 50% 50%);
            background-color: #36ff9a;
        }
    }
    <style>

    Basta colocar agora a animação como linear, para evitar as pausas (o padrão possui um ease) e adicionar um elemento acima com um overflow: false e um border-radius: 50%, de forma a ficar realmente circular:

    Controlando com Javascript

    Podemos fazer um jeitinho para que o Javascript controle a animação. Para isso, podemos usar algumas propriedades que controlam a animação. Em especial, vamos poder pausar e continuar a animação, através do parâmetro animationPlayState.

    O código completo está disponível pelo jsFiddle. O código está todo comentado e pode ser testado diretamente abaixo:

    0%




    Obs. Não use filtro blur ou muitas sombras se quiser compatibilidade com o Safari iOS.

    Provavelmente, esta não é a melhor solução para criação de um gráfico radial. Mas é interessante vermos que podemos desenvolver novas soluções, e mais leves, a partir de tecnologias mais recentes. Se você gostou, compartilhe, se tem alguma dúvida, comente. Aproveite para curtir nossa página do Facebook e entrar no grupo, através do link abaixo.