Exibindo calendários com o plugin has_calendar no Ruby on Rails
Leia em 2 minutos
O novo Spesa está sendo desenvolvido em ritmo acelerado — isso significa que ando trabalhando muito nas minhas horas vagas — e diversas funcionalidades que estou implementando estão sendo extraídas na forma de plugins.
O mais recente deles é o has_calendar, que permite exibir calendários com eventos de maneira muito simples.
A minha idéia, já que não uso Windows nem para desenvolvimento, nem para (sic) produção, foi utilizar o comando cal
, disponível em sistemas *nix, evitando toda a complexidade de ter que se trabalhar com datas. Para deixar explicíto, este plugin não irá funcionar no Windows.
Usando o plugin
Primeiro, você terá que instalar o plugin. Para isso, execute o comando script/plugin install git://github.com/fnando/has_calendar.git
.
Se você quiser exibir um calendário sem eventos, pode simplesmente chamar o helper calendar
.
<%= calendar %>
Se quiser especificar um mês específico, pode passar um hash com algumas opções.
<%= calendar :year => 2008, :month => 9 %>
O dia atual é diferenciado e não exibe o número; em vez disso o texto "TODAY" é colocado no lugar. Se quiser substituir esta mensagem, utilize a opção :today
.
<%= calendar :today => 'HOJE' %>
Para adicionar eventos, você deve passar um bloco, que receberá um objeto Date
referente ao dia do calendário. Assim, você pode realizar consultas relacionadas a esta data e exibí-las da maneira que achar melhor.
<% calendar do |date| %>
<% for schedule in Schedule.by_date(date) %>
<%= link_to schedule.title, schedule_path(schedule) %>
<% end %>
<% end %>
Como você pode perceber, isso faria até 31 consultas ao banco de dados (uma para cada dia da semana) se você não otimizasse seu código (embora eu tenha escrito o artigo assim para facilitar, minha idéia de uso ia ser totalmente diferente). Pensando nisso após ler o comentário do Carlos, decidi que seria melhor implementar uma forma onde apenas o resultado de uma consulta fosse informado.
No template, você pode definir a opção :events
, passando o resultado de sua consulta. O bloco, que antes recebia a data, agora receberá também todos os registros específicos daquele dia.
<% calendar :events => Schedule.all, :field => :scheduled_at do |date, events| %>
<% for schedule in events %>
<%= link_to schedule.title, schedule_path(schedule) %>
<% end %>
<% end %>
Melhorando a apresentação do calendário
Para formatar o calendário, você pode usar este CSS como ponto de partida.
#calendar {
border-collapse: collapse;
width: 100%;
}
#calendar td,
#calendar th {
color: #ccc;
font-family: "Lucida Grande",arial,helvetica,sans-serif;
font-size: 10px;
padding: 6px;
}
#calendar th {
border: 1px solid #ccc;
background: #ccc;
color: #666;
text-align: left;
}
#calendar td {
background: #f0f0f0;
border: 1px solid #ddd;
}
#calendar span {
display: block;
}
#calendar td.events {
background: #fff;
}
#calendar td.today {
background: #ffc;
color: #666;
}
#calendar caption {
display: none;
}
Ele irá se parecer com isto:
Mais simples, impossível! ;)
NOTA: O Mac OS X não permite iniciar a semana pela segunda-feira. Sendo assim, se você desenvolve neste sistema operacional, a semana começará no domingo. Em sistemas Linux, onde a maioria das aplicações são executadas, a semana iniciará na segunda-feira.
NOTA 2: Se você quiser utilizar este plugin no Windows, certifique-se de que exista um comando cal
no seu PATH, retornando exatamente a saída do comando para *nix. Ele deve ser executado no formato cal -m 12 2008
. Teoricamente funciona. :)
UPDATE: Este artigo foi atualizado para mostrar a nova opção :events
.
UPDATE 2: O Carlos sugeriu adicionar a chamada ao método da data no próprio helper. Claro que fica melhor! Use a opção :field
.