Pesquisar este blog

terça-feira, 30 de junho de 2015

JavaScript: alert ou console.log?



Lembro me quando comecei a desenvolver sistemas para web. Um novo universo, uma nova realidade. Não precisa compilar? Era tudo novidade! Porém, com o passar do tempo e consequentemente com o aumento da complexidade dos scripts desenvolvidos, surgiu o questionamento: Como eu "debugo" o meu script (JavaScript)?
A primeira opção a mim apresentada foi o método nativo do JavaScript "alert" e em primeira instância, pensei ter descoberto "O Santo Graal" para depuração de scripts. 
No entanto, notei que o método "alert", não era o suficiente para exibir estruturas mais complexas como o exemplo abaixo:
var produto = { Nome: 'Computer',
                  PrecoUnidade: 1110.25,
                  QuantidadeEstoque: 2
              };
Caso eu passe como parâmetro o objeto "produto", o navegador me exibirá o seguinte resultado (pouco útil):
alert(produto);
Ou seja, para objetos, o método alert() não se demonstra tão útil. E neste momento há quem apele para o uso de "alerts" personalizados para inspecionar o objeto criado:
alert("Nome: '"+produto.Nome+"', Preço: $"+produto.PrecoUnidade);

Neste  ponto, podemos chegar a conclusão de que dependendo da complexidade do objeto criado no JavaScript, o uso de alerts para "depuração" é inviável. E é neste momento em que a tecla "F12" do teclado ganha sentido. 
Na maioria dos navegadores modernos como o Chrome ou Firefox e as mais recentes versões do IE (a partir do 9), ao pressionar a tecla F12, o navegador exibe uma janela chamada comumente de "Developer Tools (Ferramentas de Desenvolvimento)".


Note que que entre as ferramentas disponibilizadas, existe o "Console", em minha opinião, a ferramenta mais poderosa dos browsers modernos. 
A princípio esta ferramenta aparentemente simples não demonstra grande importância, porém ela permite a criação e manipulação de todos os objetos existentes em uma página web em tempo de execução.
Dois fatores fazem que o Console supere de longe o método alert:

1 - Ele é discreto: não ocorre, a menos que o método alert seja invocado, a exibição de janelas no navegador.

2 - Ele é eficiente: além de não haver a necessidade de haver um arquivo JavaScript, ele possui intelisense (dependendo do navegador).

Veja como ficaria nosso exemplo anterior utilizando o método console.log([texto]) no Console do navegador:

var produto = { Nome: 'Computer',
                  PrecoUnidade: 1110.25,
                  QuantidadeEstoque: 2
              };

console.log("Nome: '"+produto.Nome+"', Preço: $"+produto.PrecoUnidade);

produto

Resultado:

Ou seja, tudo ocorre dentro do console sem a necessidade de clicar em botões "OK" ou "Cancelar" como no caso do método "alert()"

Para consultar outros métodos de output, clique aqui

quinta-feira, 25 de junho de 2015

JavaScript: 3 maneiras de se utilizar


Em certos momentos do desenvolvimento nos deparamos com certos dilemas como qual abordagem utilizar na codificação de modo a tentar se distanciar o mínimo possível das "Boas práticas de programação".
O bom, o mal e o feioQuando o assunto é "Desenvolvimento Web", nos deparamos com um bombardeio de informações, arquiteturas, frameworks, exemplos, fóruns... Com o JavaScript não é diferente.


Existem "n" modos de se efetuar chamadas a funções JavaScript e neste artigo citarei as três mais utilizadas comentando suas vantagens ou desvantagens:

1 - Inline 

Descrição: no exemplo abaixo, a chamada JavaScript é realizada dentro do evento "onload" da página.
Consideração: pior modo de utilizar.
Motivo: o script vinculado ao evento "onload" só será executado após o carregamento de todos os assets da página. Caso algum elemento da página possua dependência deste script, erros podem ocorrer. Dependendo de como o navegador interpretar o código abaixo, a função alert pode ser executada antes da renderização dos elementos contidos na tag body, impedindo o carregamento da página até que o usuário interaja com a mensagem.


<!DOCTYPE html>
<html>
<head>
    <title>Carregando o javascript</title>
</head>
<body onload="alert('inline');">
    <h1>Formas de carregamento</h1>
</body>
</html>

2 - Embed

Descrição: no exemplo abaixo, a chamada JavaScript é realizada enquanto a página é carregada
Consideração: as vezes é utilizado.
Motivo:   não interrompe o carregamento da página, pois, o script só é carregado/interpretado após o carregamento dos elementos da página e pode ser utilizado quando o conteúdo da página é dinâmico ou condicional. 
Exemplo: exibir ou não informações na página ou aplicar alguma regra de negócio sobre campos/elementos de um formulário.

<!DOCTYPE html>
<html>
<head>
    <title>Carregando o javascript</title>
</head>
<body>
    <h1>Formas de carregamento</h1>
    <script type="text/javascript">
        alert('embed');
    </script>
</body>
</html>


3 - External

Descrição: no exemplo abaixo, a chamada JavaScript é realizada a partir de um arquivo externo.
Consideração: melhor maneira.
Motivo: além da vantagem mencionada no item 2, deixa o HTML da página menos poluído, já que toda a codificação JavaScript fica em um arquivo externo.


<!DOCTYPE html>
<html>
<head>
    <title>Carregando o javascript</title>
</head>
<body>
    <h1>Formas de carregamento</h1>
    <script type="text/javascript" src="externalFile.js"></script>
</body>
</html>

externalFile.js
alert('external');
Vale ressaltar que cada navegador possui sua própria engine e efetua o parse do HTML e JavaScript de modo diferente, resultando consequentemente em comportamentos diferentes.

terça-feira, 23 de junho de 2015

Chosen: dropdownlists multi-seleção

Crie DropDownLists amigáveis, dinâmicos e multi-selecionáveis!

Encontre o que deseja através de busca viva!
No desenvolvimento Web, os controles Dropdown (tag select) acabam sendo vastamente utilizados, seja no preenchimento de um formulário ou no filtro de informações.
Selecione e remova itens de modo intuitivo!

Porém estes controles por padrão permitem a seleção de apenas uma informação, o que em alguns casos não atende aos requisitos do software desenvolvido. Existem na internet diversas empresas e frameworks pagos que possibilitam a customização e/ou adaptação destes controles para que os mesmos permitam a multi-seleção de informações. No entanto, nem sempre os resultados obtidos correspondem ao esperado e a experiência do usuário final é comprometida.
Em meio a minhas pesquisas para o desenvolvimento de uma aplicação ASP.NET MVC, encontrei o Chosen, um plugin jQuery responsável por permitir esta customização do controle @Html.DropDownList. O plugin conta com diversas opções de customização como: busca, agrupamento, multi-seleção, entre outros.
Os resultados do uso deste plugin são surpreendentes, visto que a customização do controle não apresentam alteração significativa na performance do mesmo quando aplicado sobre pequenas quantidades de dados (ex: 100 registros). Em breve publicarei alguns exemplos de uso prático deste plugin.

Para baixar o plugin, basta acessar este link!

quarta-feira, 17 de junho de 2015

Remover senha de planilha Excel

Recentemente recebi a tarefa de dar manutenção em uma página responsável pelo upload de planilhas Excel. A funcionalidade básica (upload de arquivos) funcionava perfeitamente. 
Entretanto, devido a confidencialidade das informações a serem armazenadas, a partir daquele momento, as mesmas seriam enviadas protegidas por senha. A aplicação anteriormente, utilizava o ClosedXML para efetuar a leitura e manipulação da planilha. Mas, esta API não possuía em sua documentação um método capaz de ler uma planilha criptografada (protegida por senha).
Na internet existem inúmeras APIs não gratuitas capazes de decriptar/remover senhas de planilhas, porém preferi recorrer a uma API "quase nativa" em ambientes corporativos. A solução foi apelar para o bom e velho Office.
Ao instalar o Office na máquina, o instalador registra as dlls do mesmo, podendo estas serem importadas e utilizadas no Visual Studio para automatizar operações em documentos.
Então, em busca de uma solução de menor impacto no algoritmo de importação já existente utilizado pela aplicação, codifiquei o seguinte protótipo, responsável por criar uma cópia do documento importado sem a senha, para que assim, o documento criptografado seja armazenado e o sistema efetue a leitura a partir de uma cópia descriptografada.
using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Excel.PasswordRemover
{
    class Program
    {
        static void Main(string[] args)
        {
            string password = "12345";

            //Crio as variáveis com os tipos usando pelo Excel
            Application excel = null;
            Workbooks workbooks = null;
            Workbook workbook = null;

            try
            {
                //Inicio uma instância do Excel
                excel = new Application();

                //Inicio os workbooks
                workbooks = excel.Workbooks;

                //Abro o arquivo passando a senha entre os parâmetros
                workbook = workbooks.Open(@"C:\Users\bruno\Desktop\plan1.xlsx"
                , Type.Missing, Type.Missing, Type.Missing, password, password, Type.Missing
                , Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing
                , Type.Missing);
                //Desprotejo o documento
                workbook.Unprotect(password);

                //Limpo as senhas
                workbook.Password = string.Empty;
                workbook.WritePassword = string.Empty;

                //Salvo uma "cópia" do arquivo sem a senha
                workbook.SaveAs(@"C:\Users\bruno\Desktop\plan1_no_password.xlsx"
                , Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing
                , Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlShared, Type.Missing
                , Type.Missing, Type.Missing, Type.Missing, Type.Missing);

                workbook.Close();

                excel.Quit();
            }
            catch (Exception)
            {
                //TODO: Tratar Exceptions
            }
            finally
            {
                //Garanto a finalização da instância do Excel
                Marshal.ReleaseComObject(workbook);
                Marshal.ReleaseComObject(workbooks);
                Marshal.ReleaseComObject(excel);
            }
        }
    }
}