Arquivo

Arquivo de novembro, 2010

Um objeto JavaScript para confirmar se o usuário quer sair da página

29 de novembro de 2010

Existe algumas situações que é interessante confirmar se usuário realmente quer deixar a página atual. O usuário pode sair acidentalmente sem salvar o que está editando ou quando o fluxo de edição de conteúdo da página é complexo que pode induzir o usuário a não salvar no final.

Por exemplo, no WordPress que uso nesse blog aparece uma confirmação se eu tento sair da página de edição de post sem ter salvo antes:

Clique na imagem para ampliá-la

Clique na imagem para ampliá-la

O segredo é configurar o evento onbeforeunload do objeto window com uma função que retorna o texto da confirmação:

<html>
<head>
  <script>
    window.onbeforeunload = function() {
      return "Minha mensagem de confirmação.";
    }
  </script>
</head>
<body>

</body>
</html>

Abordagem procedural

O ideal é podermos configurar se a mensagem de confirmação irá aparecer ou não, conforme as ações do usuário na página. Vamos criar uma variável que servirá como condição se a mensagem de confirmação será exibida.

<html>
<head>
  <script>
    var needToConfirm = false;

    window.onbeforeunload = function() {
      if (needToConfirm) {
        return "Minha mensagem de confirmação.";
      }
    }
  </script>
</head>
<body>
  <form onsubmit="needToConfirm = false;">
    <p><input type="text" onchange="needToConfirm = true;" /></p>
    <p><input type="submit" /></p>
  </form>
</body>
</html>

O código acima exemplifica a ativação e a desativação da exibição da mensagem de confirmação na saída da página em um formulário. Toda a vez que o valor do campo texto for alterado (linha 15), a variável needToConfirm é configurada para true. Já na submissão do formulário (linha 14) a confirmação é desativa.

Usando orientação a objetos

Agora vamos extrair essa funcionalidade para uma objeto JavaScript, salvando o código em um arquivo .js.

function ExitPageConfirmer(message) {
  this.message = message;
  this.needToConfirm = false;

  var myself = this;

  window.onbeforeunload = function() {
     if (myself.needToConfirm) {
       return myself.message;
     }
   }
}

O objeto ExitPageConfirmer recebe como parâmetro no seu construtor a mensagem de confirmação. Por padrão, a necessidade de exibir a confirmação é configurada para false. Veja um exemplo de sua utilização:

var exitPage = new ExitPageConfirmer("Minha mensagem de confirmação.");

E quando quiser ativar a exibição da mensagem de confirmação:

exitPage.needToConfirm = true;

Vamos utilizar nosso confirmador de saída de página no formulário HTML do exemplo anterior:

<html>
<head>
  <script src="scripts/Prodis.ExitPageConfirmer.js"></script>
  <script>
    var exitPage = new ExitPageConfirmer("Minha mensagem de confirmação.");
  </script>
</head>
<body>
  <form onsubmit="exitPage.needToConfirm = false;">
    <p><input type="text" onchange="exitPage.needToConfirm = true;" /></p>
    <p><input type="submit" /></p>
  </form>
</body>
</html>

Na linha 3 fizemos a referência para o arquivo .js que contém o código do confirmador e criamos uma instância de ExitPageConfirmer na linha 5. Nas linhas 9 e 10 configuramos a necessidade de exibir ou não a mensagem de confirmação utilizando usando a variável exitPage.

Detalhe sobre a implementação

Há um detalhe interessante sobre a implementação do objeto ExitPageConfirmer. Vamos ver o código novamente para ficar mais fácil de visualizar.

function ExitPageConfirmer(message) {
  this.message = message;
  this.needToConfirm = false;

  var myself = this;

  window.onbeforeunload = function() {
     if (myself.needToConfirm) {
       return myself.message;
     }
   }
}

Na linha 3 é criada a variável myself que recebe o valor de this. O this nesse escopo se refere à instância do objeto. Por exemplo, quando criamos a variável exitPage no código do formulário, o this dentro do objeto se refere a essa variável.

Dentro da função que é passada para o evento onbeforeunload do objeto window existe um if verificando o valor de needToConfirm do próprio objeto ExitPageConfirmer. Isso serve de condição para exibir a mensagem confirmação.

Mas por que não usamos this.needToConfirm ao invés de myself.needToConfirm na linha 8?

Acontece que a partir do momento que estamos configurando algo dentro do objeto window, o this se refere ao objeto window e não mais ao objeto ExitPageConfirmer. Sendo assim, criamos a variável myself que recebe uma referência da instância atual do objeto ExitPageConfirmer.

Como a variável myself fica disponível também no escopo da função que é atribuída ao evento onbeforeunload do objeto window, podemos utilizá-la sem problemas.

O escopo da variável myself se limita ao construtor de ExitPageConfirmer, então a mesma não pode ser acessada de fora do objeto.

Conclusão

O objeto ExitPageConfirmer pode ser utilizado em qualquer página, evitando assim a duplicidade de código. Além disso, o uso de programação orientada a objetos em JavaScript, ao invés de abordagem procedural, torna o código mais elegante e fácil de manter.

O código completo você encontra aqui no meu Github.

Referência:
Asking Users To Confirm If They Wish To Leave The Page

JavaScript , , , , ,

Samsung 10K Corpore São Paulo Classic - 9º Troféu Zumbis dos Palmares

24 de novembro de 2010

No domingo de 21 de novembro de 2010 corri os 10 km da Samsung 10K Corpore São Paulo Classic - 9º Troféu Zumbis dos Palmares.

A corrida foi disputada numa bela manhã de sol, nos arredores do Parque do Ibirapuera e foi organizada pela Corpore.

Tempo total: 00:54:52

Tempo médio por km: 05:29

Tempo em cada km:

  1. 04:55
  2. 05:00
  3. 05:18
  4. 05:43
  5. 05:17
  6. 06:00
  7. 05:50
  8. 05:41
  9. 05:37
  10. 05:11

Foto de WebRun

Foto de WebRun

Foto de WebRun

Foto de WebRun

Foto de MidiaSport

Foto de MidiaSport

Foto de WebRun

Foto de WebRun

Esportes , , , , ,

Como testar gravação de log em Ruby on Rails

17 de novembro de 2010

Em uma aplicação Ruby on Rails, quando você precisa assegurar nos seus testes que a gravação de logs está sendo realizada com sucesso, não há a necessidade de abrir o arquivo físico de log, ler seu conteúdo e verificar se a informação que você deseja está lá.

Ao invés disso, você pode substituir a saída de escrita padrão do log por outra classe de stream, como a StringIO, onde você terá fácil acesso ao que for gravado no log durante o teste.

Log em inglês também é tronco, lenha.

Log em inglês também é tronco, lenha.

Vamos ver um exemplo utilizando RSpec para testar a gravação de log de um método chamado do_something em uma classe modelo SomeModel.

require 'spec_helper'

describe SomeModel do
  before(:each) do
    @some_model = SomeModel.new

    @log_stream = StringIO.new
    @some_model.stub(:logger).and_return(Logger.new(@log_stream))
  end

  describe "#do_something" do
    it "logs info" do
      @some_model.do_something
      @log_stream.string.should include("I am logging something")
    end
  end
end

Na linha 7, criamos uma instância de StringIO atribuindo à variável @log_stream. É nesse objeto que serão gravados todos os logs do nosso teste. Para isso, na linha 8, substituímos o logger original por um stub de Logger que faz referência à instância da classe StringIO que criamos.

Já na linha 14, a asserção do nosso teste verifica se o texto correto foi gravado no stream do log. O método StringIO#string retorna a string bruta, ou seja, o texto que foi gravado no stream.

A seguir está a implementação do método do_something:

class SomeModel < ActiveRecord::Base
  def do_something
    # some implementation

    logger.info "I am logging something"
  end
end

Para fazer testes de gravação de logs em controllers, a idéia é a mesma, basta apenas usar o stub no método logger do controller (linha 6):

require 'spec_helper'

describe SomeModelsController do
  before(:each) do
    @log_stream = StringIO.new
    controller.stub(:logger).and_return(Logger.new(@log_stream))
  end

  describe "GET index" do
    it "logs info" do
      get :index
      @log_stream.string.should include("Now logging in a controller")
    end
  end
end
class SomeModelsController < ApplicationController
  def index
    # implementation

    logger.info "Now logging in a controller"
  end
end

Se você precisa usar log em uma classe que não seja um modelo ou controller, não vai poder chamar o método logger diretamente. Por exemplo, a classe a seguir, foi criada dentro da pasta lib de uma aplicação Rails.

class CoolClass
  def cool_method
    logger.info "Cool log!"
  end
end

Chamando o método cool_method teremos o seguinte erro:
> c = CoolClass.new
> c.cool_method
NameError: undefined local variable or method `logger’ for #<CoolClass:0×1e81bf0>

Resolver isso é simples, basta utilizar Rails.logger:

class CoolClass
  def cool_method
    Rails.logger.info "Cool log!"
  end
end

E no teste para gravação de log o stub é feito na classe Rails (linha 8):

require 'spec_helper'

describe CoolClass do
  before(:each) do
    @cool_class = CoolClass.new

    @log_stream = StringIO.new
    Rails.stub(:logger).and_return(Logger.new(@log_stream))
  end

  describe "#cool_method" do
    it "logs info" do
      @cool_class.cool_method
      @log_stream.string.should include("Cool log!")
    end
  end
end

Ruby, TDD , , , , ,

[InfoQ] Lançado o ASP.NET MVC 3 Release Candidate

10 de novembro de 2010

Acaba de ser lançada a Versão 3 Release Candidate do ASP.NET MVC, o framework Model-View-Controller de .NET, trazendo uma série de novos recursos, melhorias em ferramentas e correções de bugs.

Vamos ver alguns recursos inclusos no ASP.NET MVC 3 RC.

Veja a notícia completa na InfoQ Brasil:
http://www.infoq.com/br/news/2010/11/aspnet-mvc-rc

Veja também outras notícias e artigos sobre .NET na InfoQ Brasil:
http://www.infoq.com/br/dotnet

.NET , ,

Revendo amigos na RubyConf Brasil 2010

9 de novembro de 2010

Na última semana de outubro de 2010, participei da RubyConf Brasil 2010, evento organizado pela Locaweb, que teve a participação de quase 700 participantes.

Além das ótimas palestras, também foi a oportunidade de rever alguns amigos.

Cauê Guerra, Pedro Mariano, Eu e David Paniz

Cauê Guerra, Pedro Mariano, Eu e David Paniz

Eventos , ,

[InfoQ] C# 5.0 terá sintax sugar para operações assíncronas

4 de novembro de 2010

O time de desenvolvimento de .NET da Microsoft anunciou nessa última semana que a próxima versão da linguagem C# terá uma nova sintaxe, mais enxuta, para realizar operações assíncronas.

Atualmente, para realizar uma tarefa assíncrona é necessário utlizar callbacks, seja declarando métodos separados ou utilizar métodos anônimos.

No C# 5.0, com a utilização dos novos comandos async e await, essa tarefa ficará muito mais fácil de escrever.

Veja a notícia completa na InfoQ Brasil:
http://www.infoq.com/br/news/2010/11/csharp-5-sintax-sugar

Veja também outras notícias e artigos sobre .NET na InfoQ Brasil:
http://www.infoq.com/br/dotnet

.NET , , , ,

[InfoQ] Livro grátis: Moving to Microsoft Visual Studio 2010

4 de novembro de 2010

A Microsoft Press está disponibilizando um livro grátis chamado “Moving to Microsoft Visual Studio 2010″, dos autores Patrice Pelland, Pascal Paré e Ken Haines. O objetivo desse livro é ajudar os desenvolvedores .NET na transição de versões anteriores do Visual Studio para a última versão, o Microsoft Visual Studio 2010.

Veja a notícia completa na InfoQ Brasil:
http://www.infoq.com/br/news/2010/11/livro-moving-visual-studio-2010

Veja também outras notícias e artigos sobre .NET na InfoQ Brasil:
http://www.infoq.com/br/dotnet

.NET, Livros , , ,

Novidades e artigos sobre .NET na InfoQ Brasil

4 de novembro de 2010

Desde que estive presente na QCon São Paulo 2010, notei que a publicação de conteúdo sobre .NET na InfoQ Brasil não estava muito frequente. Mesmo tendo no evento uma track de .NET bastante interessante, isso não era refletido no site da comunidade.

InfoQ.com (Fila de Informação) é uma comunidade online independente focada na mudança e inovação no desenvolvimento do software corporativo, almejando primariamente no arquiteto técnico, no líder técnico (desenvolvedor sênior) e no gerente de projeto. InfoQ dá assistência as comunidades de Java, .NET, Ruby, SOA, e Agile com notícias diárias escritas por experts, artigos, entrevistas em vídeo, apresentação de vídeo conferência e mini-books.

Há um tempo atrás havia conversado com o Pedro Mariano, quando ele estava iniciando como editor-chefe da InfoQ, a respeito de escrever sobre .NET. Nessa época, estava numa transição de projetos de .NET para Ruby no meu trabalho, o que acabou consumindo bastante meu tempo de estudo.

Agora que já aprendi um pouquinho de Ruby e trabalhando com Rails diariamente, consigo contribuir com alguns artigos e notícias de .NET para a InfoQ Brasil. Para mim acaba sendo uma oportunidade de me manter atualizado sobre .NET, plataforma com a qual trabalhei por mais de 6 anos e que atualmente não tenho contato diário. Além disso, é mais uma forma de compartilhar conhecimento.

Pretendo escrever no mínimo uma vez a cada 15 dias. Havendo possibilidade, escreverei com mais frequência.

Agradeço a InfoQ Brasil, que é mantida pela Caelum, pela oportunidade. Também agradeço ao Pedro Mariano e David Paniz, com os quais tive oportunidade de trabalhar junto, pelo incentivo.

.NET , ,