DayPilot Scheduler Control for ASP.NET

Fonte: http://www.codeproject.com/KB/webforms/daypilot_scheduler.aspx

Features

Main features:

  • Simple and clean look
  • Multiple resources on the Y axis
  • Customizable time scale on the X axis (one cell = 1 minute, 1 hour, 1 day, 1 week …)
  • Highlights business hours (customizable color)
  • Automatically handles concurrent events
  • Customizable event box (text, size, background color, duration bar…)
  • Customizable fonts and colors

Database connectivity:

  • DataSource and DataSourceID properties supported
  • SqlDataSource
  • XmlDataSource
  • DataTable
  • DataSet
  • ArrayList
  • and other sources…

Event handling:

  • Free time slot click event (automatic PostBack or manual JavaScript handling)
  • Calendar event click event (automatic PostBack or manual JavaScript handling)

Licensing:

  • Open-source (Apache Software License 2.0)

Compatibility:

  • Internet Explorer 6
  • Internet Explorer 7
  • Firefox 2
  • Firefox 3
  • Opera 9
  • Safari 2
  • Safari 3
  • Google Chrome 1

Background Information

DayPilot Scheduler reuses the event arranging algorithms introduced in the DayPilot Calendar control (Outlook-like day and week view calendar/scheduler):

DayPilot Calendar detects blocks of overlapping events so they could be displayed properly. The width of each event box is adjusted according to the number of concurrent events:

DayPilot Calendar detects blocks of overlapping events so they could be displayed properly. The width of each event box is adjusted according to the number of concurrent events:

DayPilot Scheduler uses the same arranging algorithm but the layout is different:

  • The Scheduler shows the time on the X axis.
  • Event box height is fixed.
  • Concurrent events are handled by increasing the row height, not by shrinking the event box.

This reduces the concurrency problem: The increasing number of concurrent events doesn’t reduce readability.

See Also

Minimum Setup Sample

Collapse | Copy Code
<DayPilot:DayPilotScheduler
  ID="DayPilotScheduler1"
  runat="server"
  DataSourceID="SqlDataSource1"
  DataStartField="start"
  DataEndField="end"
  DataTextField="name"
  DataValueField="id"
  DataResourceField="resource"
  StartDate="2009-01-01"
  CellDuration="60"
  Days="1" >
    <Resources>
      <DayPilot:Resource Name="Room A" Value="A" />
      <DayPilot:Resource Name="Room B" Value="B" />
      <DayPilot:Resource Name="Room C" Value="C" />
    </Resources>
</DayPilot:DayPilotScheduler>

The first group properties defines the data binding:

  • DataSourceID
  • DataStartField (starting DateTime)
  • DateEndField (ending DateTime)
  • DataTextField (event text)
  • DataValueField (event id)
  • DataResourceField (resource id)

DataResourceField is important – the values from this column will be matched with the resource IDs (Resource.Value).

The second group defines the time range and scale:

  • StartDate (first visible day)
  • Days (number of visible days)
  • CellDuration (cell duration in minutes)

And finally, it’s necessary to define the resources (rows):

  • Resource.Name (row name)
  • Resource.Value (row ID)

Usage Examples

Daily Scheduler

Settings:

Collapse | Copy Code
Days="1"
CellDuration="60"

StartDate is set manually in the code behind:

Collapse | Copy Code
DayPilotScheduler1.StartDate = DateTime.Today;

Weekly Scheduler

Settings:

Collapse | Copy Code
Days="7"
CellDuration="1440"

The first day of week is calculated using Week.FirstDayOfWeek helper:

Collapse | Copy Code
DayPilotScheduler1.StartDate = Week.FirstDayOfWeek(DateTime.Today, DayOfWeek.Monday);

Monthly Scheduler

Settings:

Collapse | Copy Code
CellDuration="1440"

In this case, it’s necessary to set the Days property manually:

Collapse | Copy Code
DayPilotScheduler1.StartDate =
	new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
DayPilotScheduler1.Days =
	DateTime.DaysInMonth(DateTime.Today.Year, DateTime.Today.Month);

Free/Busy Visualisation

This view doesn’t show event name (DataTextField is bound to an empty column).

Settings:

Collapse | Copy Code
DurationBarVisible="false"
EventBackColor="#4A71CE"

Timeline Visualisation

In the timeline view, the resources are replaced with events in the row headers. There is always just one event per row.

Settings:

Collapse | Copy Code
DurationBarVisible="false"
EventBackColor="#CA2A50"

HTML5: 10 duras verdades

O momento é propício para admitir que existem limitações sérias com o modelo.

Por Peter Wayner, InfoWorld

Para muitos profissionais de TI, o HTML5 representa a chegada de algumas novas características interessantes, com potencial para provocar uma mudança de paradigma na programação Web. Polvilhe um pouco de HTML5 em seu código e seus sites serão mais rápidos e mais extravagantes. Mas a realidade do que HTML5 pode fazer por aqueles que procuram APPs na Web está aquém do hype.

O momento é propício para admitir que existem limitações sérias com o modelo. Não só há razões para lamentar sobre o fato de o HTML5 não realizar todos os nossos sonhos de atingir o nirvana na Web, como até mesmo razões para abster-se de usar o HTML5, em alguns casos.

A verdade é que, apesar de suas capacidades poderosas, o HTML5 não é a solução para todos os nossos problemas. Suas características adicionais são convincentes e ajudam a tornar aplicativos Web concorrentes formidáveis para aplicativos nativos, mas questões com segurança, limitações para armazenamento local de dados, os desafios de sincronização e as políticas de uso, deveriam ser suficientes para frear todas as expectativas. Afinal, cada tecnologia tem suas limitações.

Listamos dez duras verdades que os desenvolvedores Web devem considerar para tirar o máximo do HTML5.

1:: Segurança é um pesadelo
Na ponta cliente, o problema fundamental é que o usuário final tem controle sobre o código executado na máquina. No caso de aplicações Web, quando o seu browser vem com uma ferramenta de depuração, é mais fácil do que nunca abusar desse controle.

Com um depurador JavaScript como o Firebug, quem tem alguma curiosidade sobre o que o Facebook, o Google, ou qualquer outro site está fazendo pode simplesmente começar a inserir breakpoints e ver o código. Isso é ótimo para depurar e aprender como operar sites, mas também é um pesadelo para a segurança.

Suponha que você tenha o interesse em mudar o valor de uma variável. O Firebug ou qualquer um dos depuradores presentes em outros navegadores pode ajudá-lo a ajustar as variáveis como você desejar. Quer enganar seus amigos e fazê-los crer que você está em determinado local, longe do local onde você de fato está? É fácil editar as variáveis latitude e longitude para colocar seu browser em qualquer lugar do mundo. Todas as características puras do seu aplicativo Web podem ser modificados, e o browser torna mais fácil essa modificação do que um APP de código nativo.

Isso significa que os aplicativos baseados em clientes HTML5 podem não ser confiáveis para a coleta dos dados, e é melhor para que todos tenham consciência de suas capacidades.

2 :: O armazenamento local de dados é limitado
A permissão para o armazenamento de até 4GB de dados estruturados pelo banco de dados presente no browser, no lado do cliente – de forma parecida a como vinha ocorrendo com o uso de cookies, mas tentando eliminar as limitações impostas, como o tamanho de 4Kb – é uma das funcionalidades mais badaladas do HTML5.

O desenvolvedor deve lembrar, no entanto, que o armazenamento local é por site e estará disponível para seus scripts toda vez que o site que originalmente armazenou os dados for acessado, de modo a poupar largura de banda e melhorar o desempenho.

E também que os banco de dados dos browsers não dão aos usuários o mesmo poder sobre seus dados que eles teriam em outros aplicativos.

Por exemplo: o usuário não pode mover os dados armazenados para outra máquina, fazer cópias, fazer um backup, ou abri-lo com um aplicativo diferente do navegador. Os arquivos não são projetados para se mover facilmente, embora seja possível fazê-lo se o usuário souber onde e como localizá-los. Até porque, não são como planilhas ou documentos de texto, fáceis de abrir com qualquer editor.

3:: Dados locais podem ser manipulados
O usuário não pode ter controle sobre os dados armazenados localmente, mas o site central também pode ter problemas por causa com a sincronização e até mesmo com a segurança desses dados.

Não há como o desenvolvedor garantir que o banco de dados local nunca será manipulado pelo usuário. Embora não existam ferramentas que tornem a edição dos dados locais e/ou a atualização de privilégios, tarefas fáceis para os usuários, ainda assim elas podem vir a ocorrer. Brechas de segurança do código JavaScript, por exemplo, são apenas um dos caminhos possíveis para tal.

4:: A sincronização dos aplicativos offline é um pesadelo
A possibilidade de armazenamento local de dados local do HTML5 melhora imensamente a capacidade de usar aplicativos Web no modo offline. O único problema é a sincronização de dados.

Se um aplicativo Web está conectado à Internet, pode sempre salvar os dados para a nuvem. Quando está offline, as alterações não são sempre armazenados na nuvem. Quando alguém muda de navegador ou usa uma máquina diferente, cópias começam a proliferar e as dificuldades de sincronização também.

Os desenvolvedores devem se preocupar em fornecer a interface para que o usuário possa lidar com a sincronização. A especificação HTML5 não oferece qualquer ajuda.

Programadores gerenciar essas dores de cabeça utilizando sistemas de controle de versão, que se tornaram cada vez mais sofisticados para lidar com esse problema. No entanto, apenas ter a tecnologia não significa que ela seja de fácil uso. A fusão de vários repositórios GIT pode levar tempo.

5:: A nuvem lhe deve nada
Não é justo culpar HTML5 por todos os problemas estruturais com o armazenamento de dados na nuvem, mas a nuvem é uma parte essencial do modelo, que tira proveito dela para corrigir todas as dores de cabeça da instalação de software e backup de dados.

Dadas as limitações de armazenamento local de dados do HTML5, a maior parte do armazenamento de dados das APPs Web continuará nos servidores, e há momentos em que esta abordagem poderá ser devastadora.

Recentemente o Facebook decidiu que não gostava de um plug-in baseado em Linux para fazer upload de fotos. O plug-in foi removido, juntamente com todas as fotos que foram enviadas ao usá-lo.

Essas histórias não são comuns, mas estão se tornando cada vez mais frequentes, por muitas razões. E podem vir a ser um problema ainda maior se considerarmos que muitos termos de serviço de aplicações Web não responsabilizam os fornecedores por perdas de dados, deixando o usuário sem nenhum recurso legal para recuperá-los. Alguns dos acordos de serviço mais ultrajantes insistem que os dados podem até mesmo serem excluído sem “nenhuma razão” para tal.

A estrutura do HTML5 praticamente garante que qualquer do dado em cache local no navegador do usuário será armazenado na nuvem, fora de seu alcance e controle. O hype HTML5 diz que esta é uma característica fantástica, mas esquece que ele pode se voltar facilmente contra o modelo.

6:: Upgrades forçados não são para todos

Uma história, apócrifa, circula na rede. Consta que determinada pessoa usou uma conta de Gmail para conexões casuais com pessoas em bares. Quando o Google+ foi lançado, todas as lembranças dessas pessoas vieram à tona, porque endereços antigos para os fóruns de discussão voltaram à superfície. Todos os dias, velhos conhecidos reaparecem lá pedindo para serem incluídos em círculos de discussão.

Quando as empresas Web necessitam fazer o upgrade de seus serviços, normalmente o fazem de uma vez, contemplando todos os usuários ao mesmo tempo. Se, por um lado, isso livra os usuários de terem que gerenciar a instalação do upgrade, por outro acaba virando um pesadelo para qualquer um que não queira usar os novos recursos.

E este não é apenas um problema para a privacidade das pessoas, como no caso acima.

7:: Web Workers não oferecem priorização

eb Workers estão entre os recursos mais intrigantes do HTML5. Ele acelera o carregamento de páginas web cheias de código javascript, por ser capaz de executá-los em processos separados do restante da página web. Em outras palavras, o HTML5, com o Web Workers permite que o navegador se comporte como um sistema operacional, ainda que parcialmente.

Infelizmente, não há maneira de gerenciar a carga de trabalho de forma eficaz ou de definir prioridades.

8:: Incompatibilidades de formato abundam

Não culpe os comitês do HTML5 pelo fato de os desenvolvedores de browsers não tenham decidido implementar todos os vários formatos áudio e vídeo. São os desenvolvedores que têm que lidar com as consequências quando um arquivo que funciona perfeitamente em um browser não faz nada em outro. Há um teste para isso? Desenvolvedores de API foram espertos o suficiente para incluir a função canPlayType, mesmo que ela não seja suportada por todos os navegadores.

9:: Implementações são browser-dependentes

A visão idílica do HTML5 é uma coisa, a realidade grungy de suas implementações é outra. Verdade. Os programadores estão tentando fazer o seu melhor para construir os sonhos dos arquitetos, mas algumas tags e objetos não funcionam corretamente.

Por exemplo, há muitos desejos sobre a API de geolocalização do HTML5. Ela oferece alguma proteção para a privacidade e um pouco de controle sobre a precisão. Mas em determinado browser, sempre dá time out.

Em última instância, esta é mais uma reclamação sobre como os navegadores não conseguem implementar recursos HTML5 de forma consistente, ao contrário de um ser que visa a estrutura da API em si.

10:: Idiossincrasias de hardware impõem novos desafios

Também parece injusto reclamar sobre como alguns desenvolvedores de browser vão além do dever de proporcionar um desempenho muito melhor. Mas nenhuma boa ação fica impune.

A Microsoft tem feito um grande trabalho de melhorar o desempenho de objetos Canvas no IE, integrando-os com os drivers de baixo nível de hardware. A empresa encomendou jogos simples, como pirateslovedaisies.com, para demonstrar o recurso.

Mas agora os programadores devem prestar atenção para saber se esse recurso adicional está disponível ou não, e se seu código está sendo executado.

Fonte: idgnow.uol.com.br

******************************************

CONHEÇA AS VANTAGENS DO  MICROSOFT SHAREPOINT

tela SharePoint

A Plataforma de Colaboração Corporativa para a Empresa e a Internet.

Consulte a DANRESA e saiba mais.

União Europeia alerta para problemas de segurança do HTML5

Bloco econômico encontrou 51 vulnerabilidades, mas algumas são inerentes ao padrão. Usuários terão de tomar cuidado para não cair em armadilhas.

A agência de segurança digital da União Europeia (ENISA, na sigla em inglês) alerta que os padrões sobre os quais o HTML5 está sendo desenvolvido negligenciam importantes questões quanto à proteção contra ataques. Nesta segunda-feira (1/08) ela divulgou um documento de 61 páginas, no qual analisa as especificações da tecnologia.

O HTML5 é de responsabilidade do Consórcio World Wide Web (W3C). A organização aceita comentários a respeito da última prévia do HTML5 – liberada há dez dias – até essa terça-feira (2/08), ou seja, a União Europeia enviou suas sugestões pouco antes do término do prazo.

“Penso que é importante que, logo no primeiro rascunho, já se observe as especificações tendo a segurança como uma das prioridades”, afirmou Giles Hogben, diretor da agência. Ele destaca a importância dessas diretrizes, pois serão usadas como referências por muitos anos – tal qual o que ocorreu com o HTML4, cujas especificações foram liberadas em 1999.

Se, por exemplo, os códigos quanto ao uso da tecnologia em navegadores não forem bem estudados, usuários finais e corporativos estarão em risco. “Todos utilizam browsers nos dias de hoje”, disse Hogben. “É uma questão crucial”.

A ENISA encontrou 51 vulnerabilidades. Alguns dos problemas podem ser corrigidos a partir de simples mudanças, outras são inerentes aos próprios recursos, de modo que os usuários devem ser alertados para se protegerem. Uma das funções que chamaram a atenção da agência corresponde aos novos tipos de formulários a serem usados.

Com o HTML5 será possível inserir um botão em uma página com formulários, posicionando-o em qualquer lugar. Segundo os especialistas, crackers poderão tirar proveito do recurso, colocando seu próprio ícone no portal, e levando usuários a clicarem onde não deveriam, enviando dados confidenciais aos criminosos.

“Não estamos recomendado que o recurso seja retirado, apenas queremos que os usuários tenham acesso às informações necessárias para que não caiam em golpes”, ressaltou Hogben.

A agência também fez recomendações quanto ao modo como os internautas devem se comportar na hora de fazer transações financeiras. Eles devem usar diferentes navegadores ou, pelo menos, ativar o sand boxing, quanto abrirem múltiplas abas. Isso evitará com que o invasor, ao comprometer uma página, espalhe sua praga para outros locais que não a própria aba infectada.

A ENISA continuará enviando suas conclusões aos grupos envolvidos com o W3C. Em janeiro de 2012, novas especificações deverão ser liberadas, tendo em conta as sugestões recebidas.

(Jeremy Kirk)
 
*********************************
Conheça o WEBTITAN

Poderosa solução de “Web Filtering” que provê ricas funcionalidades e permite o gerenciamento e a proteção dos usuários quando estão navegando na internet.

Generate RSS Feed in ASP.Net

RSS feed is an xml formatted document that gives user the capability to read frequently updated contents on our websites without visiting our site. RSS feed has become one of the most sophisticated mechanism to share information on the internet world. It is one of the web 2.0 features which allows users to read their relevant information’s available on the internet. All we need to do is, get the RSS feed URL from different sites of our interest and subscribe it on our RSS reader. Before moving to actual implementation of RSS feed we will understand the format of RSS feeds that a RSS reader can consume.

For example, CodeDigest Rss feed will look like,

<?xml version=”1.0″ encoding=”utf-8″ ?>

<rss version=”2.0″>

  <channel>

  <title>CodeDigest.com Latest Articles</title>

  <link>http://www.codedigest.com</link&gt;

  <description>Latest articles hosted on CodeDigest.com.</description>

  <item>

  <title>Useful Datagrid Tips</title>

  <description>There are some frequent queries that are being asked in most of the forums and UG’s regarding datagrid. I have compiled a list of useful tips from my previous posts and posted it here.</description>

  <link>http://www.codedigest.com/Articles/ASPNET/77_Useful_Datagrid_Tips.aspx</link&gt;

  <pubDate>4/29/2008 9:47:12 AM</pubDate>

  </item>

</channel>

  </rss>

As we can see the above XML, the whole contents are packed inside <rss> tag. The actual information about the posts is kept inside <item> tag which in turn is packed inside a <channel> tag.  Moving forward this article will help us understand constructing an RSS feeds for our asp.net sites.

What we need to do?

Generating RSS feed for our website is nothing but emitting the frequently updated data in the above specified XML format. It can be done by constructing the XML document and performing a Response.Write of the constructed XML document.

 What should we use?

Our requirement can be achieved by performing a Response.Write on an ASPX page. But, in this article we will generate our RSS feed using HttpHandler instead of an ASPX page. There are some advantages in using HttpHandler over an ASPX pages, an ASPX page will have a series of events like OnInit, Page load, etc  which is not at all required in our case. These page level events are over head since we just want to get the data from database and construct a XML document and output the raw xml.

Implementation

With the RSS feed XML format in mind, we can construct XML using XmlTextWriter class. Include an HttpHandler to our project by right clicking solution and clicking “Add New Item”. Refer the below figure.

 

RSS.ashx

<%@ WebHandler Language=”C#” %>

 

using System;

using System.Web;

using System.Data;

using System.Text;

using System.Xml;

using DataAccess;

  public class Rss : IHttpHandler {

     ArticleDAO articleDAO = new ArticleDAO();

     public void ProcessRequest (HttpContext context) {

         // Clear any previous output from the buffer

           context.Response.Clear();

                   context.Response.ContentType = “text/xml”;

               XmlTextWriter cdRSS = new XmlTextWriter(context.Response.OutputStream, Encoding.UTF8);

 

        cdRSS.WriteStartDocument();      

 

        cdRSS.WriteStartElement(“rss”);

 

        cdRSS.WriteAttributeString(“version”, “2.0”);       

 

        cdRSS.WriteStartElement(“channel”);

 

        cdRSS.WriteElementString(“title”, “CodeDigest.com Latest Articles”);

 

        cdRSS.WriteElementString(“link”, “http://www.codedigest.com&#8221;);

 

        cdRSS.WriteElementString(“description”, “Latest articles hosted on CodeDigest.com.”);

 

        cdRSS.WriteElementString(“copyright”, “Copyright 2008 – 2009 CodeDigest.com. All rights reserved.”);

 

       //Connect database to get the data

        DataTable dtArticles = articleDAO.GetArticlesForRss();

 

        for (int i = 0; i < dtArticles.Rows.Count; i++)

        {

       //Build Item tags with the data from database

            cdRSS.WriteStartElement(“item”);

 

            cdRSS.WriteElementString(“title”, dtArticles.Rows[i][“Title”].ToString());

 

            cdRSS.WriteElementString(“description”, dtArticles.Rows[i][“description”].ToString());

 

            cdRSS.WriteElementString(“link”, “http://”+ context.Request.Url.Host + dtArticles.Rows[i][“URL”].ToString());

 

            cdRSS.WriteElementString(“pubDate”, dtArticles.Rows[i][“ApprovedOn”].ToString());

 

            cdRSS.WriteEndElement();

        }

 

        cdRSS.WriteEndElement();

 

        cdRSS.WriteEndElement();

 

        cdRSS.WriteEndDocument();

 

        cdRSS.Flush();

 

        cdRSS.Close();

 

        context.Response.End();     

 

    }

 

    public bool IsReusable {

        get {

            return false;

        }

    }

}

Font:  http://www.codedigest.com/Articles/ASPNET/86_Generate_RSS_Feed_in_ASPNet.aspx 

*********************************************

Soluções em desenvolvimento de sistemas com a DANRESA Consultoria.

Adobe começa a ‘alugar’ o Photoshop

Empresa investe em solução para reduzir pirataria

Procurando lucro com novos modelos de negócios, a desenvolvedora de software Adobe divulgou no início desta semana seu plano de assinaturas para seus principais programas, como o editor de imagens Photoshop, o software multimídia Flash e o editor de sites Dreamweaver. O sistema de “aluguel” vai permitir o uso dos produtos por um tempo determinado, com valor praticamente simbólico perto do preço original dos serviços.

O Photoshop, por exemplo, custará 49 dólares por mês, enquanto sua versão comercial não sai por menos de 699 dólares. Caso seja necessário alugar mais de um produto, o pacote Photoshop, Illustrator, inDesign e Acrobat Pro sai por 99 dólares ao mês. A soma das caixas de todos esses programas não sairia por menos de 1.300 dólares.

Segundo a empresa, a novidade é voltada principalmente aos pequenos negócios e profissionais liberais da área de design gráfico e vídeo. “Todos os produtos oferecidos nesse modelo são instalados na sua máquina e oferecem os mesmos recursos das versões completas”, apontou o comunicado oficial da companhia Adobe.

O grande desafio da Adobe na atualidade é o combate à pirataria de software. Anualmente, a companhia procura renovar sua linha de produtos com novas versões dos aplicativos, que acabam caindo em redes de troca de arquivos, onde são baixados ilegalmente.

fonte: http://veja.abril.com.br

Você está pronto para o HTML 5 ?

 

Quem acompanhou o começo da web deve lembrar do quanto as primeiras páginas eram feias. O design de páginas com HTML puro era cinza, quadradão, feito na base de frames e tabelas, as animações eram arquivos GIF toscos e restava ao webmaster fazer graça com scripts inúteis. Nesses últimos anos, vários padrões e tecnologias surgiram para ajudar a linguagem, como o CSS, o Flash e o XHTML. Mesmo assim, chegou a hora de mais mudança. A nova versão do padrão HTML está mais sólida, com os principais navegadores suportando suas inovações e facilitando assim a vida do designer, que poderá dispensar bibliotecas e pacotes auxiliares.

Vale lembrar que nem tudo funciona em todos os browsers, já que, na falta de uma especificação definitiva (que está prevista para 2012), os empresas adicionam os recursos do HTML 5 nos navegadores a conta-gotas. Conheça, a seguir, as principais mudanças que já estão aprovadas pela W3C e pelo WHATWG, as entidades que decidem o futuro da linguagem HTML.

Multimídia sem plug-in

O conteúdo em áudio e vídeo na web é refém dos plug-ins, como o Flash, para ser exibido. O HTML 5 prevê uma forma de contornar isso com as tags <video> e <:audio>. Falta ainda definir os tipos de codecs a ser utilizados universalmente com essas tags. Hoje, Chrome e Safari conseguem exibir filmes em H.264 e tocar áudio AAC, encapsulados num arquivo MP4. Já o Firefox, fiel aos padrões abertos, mostra só vídeos Theora e som Vorbis, dentro de um arquivo Ogg. O impasse não preocupa tanto, pois as tags <video> e <:audio> podem receber mais de um arquivo, com o browser selecionando qual é a opção compatível. Para adicionar um vídeo à página, basta usar o código:

<video src="meuvideo.mp4 width="320" height="240" controls></video>

CSS arrumadinho

O novo HTML promete aposentar frames e tabelas das páginas, com o CSS efetivado como responsável para esse fim. Além disso, a versão 5 conta com tags para definir seções dos sites, facilitando a integração com as folhas de estilo. Atualmente, o normal é usar um elemento <div>, com seu nome indicando o tipo de seção. As novas tags são <header>, <footer>, <article>, <section>, <nav> e <aside>. Elas definem o cabeçalho, o rodapé, um artigo, uma seção (de um artigo), a barra de navegação e anotações sobre o conteúdo. Com esses elementos, é criada uma padronização que facilita a localização de conteúdo pelos buscadores e o reaproveitamento dos arquivos CSS.

Gráficos nascidos na web

O elemento <canvas> permite criar desenhos usando JavaScript. Assim é possível, por exemplo, transformar dados do site em gráficos dinâmicos. A tag também serve para usar um texto ou imagem como substituto do desenho, caso o browser não tenha suporte aos gráficos dinâmicos. Nesse caso, o conteúdo alternativo fica entre e <canvas> e </canvas>.

Calendários sem erro

Qual é a data definida por 10/2/2010? Pode ser 10 de fevereiro, no padrão usado no Brasil, e, ao mesmo tempo, 2 de outubro, no modelo americano. O HTML 5 pode contornar essas situações com tags que definem o tipo de dados e sua formatação no texto da página web. A tag <time> marca hora e data e evitaria o problema descrito acima usando o código <timedatetime=”2010-02-10″> </time>, que poderia identificar as informações do navegador e decidir qual seria a data correta, para que ela possa ser exibida no padrão do usuário.

Versão offline

Já ouviu falar no Google Gears? Ele transforma aplicativos web em programas que rodam no browser mesmo em máquinas sem conexão com a web. Essa mágica é feita pelo recurso DOM Storage, que poderá ser usado por qualquer site em HTML 5. Um ponto essencial dessa forma de armazenamento local é que o servidor remoto não pode acessar diretamente o conteúdo (diferentemente dos cookies). Somente o browser e os scripts da página acessada podem modificar o conteúdo offline. Hoje, cada browser usa um limite de espaço. O Firefox aloca no máximo 5 MB por domínio web acessado. Já o Internet Explorer libera 10 MB por base de dados criada, independentemente do domínio.

Muito além dos cliques

Existem várias bibliotecas para habilitar o suporte ao recurso de arrastar e soltar objetos em sites. Mas no HTML 5 a coisa fica bem mais fácil. Basta definir valores para três eventos em JavaScript: dragenter, dragover e drop. Eles indicam, respectivamente, a entrada e a passagem de um elemento sobre outro, além do evento para o momento em que um item é solto. Definir um elemento da página como item que pode ser arrastado é mais fácil ainda. Basta adicionar a definição draggable=”true” a ele.

Fonte: Info

Comentário: O HTML 5 vem pra reorganizar o festival de TAGs que são utilizadas hoje para exibir vídeos, animações ou personalizar nosso layout, criadas a partir da evolução da Internet. Creio que a nova linguagem vai ajudar e muito os desenvolvedores e novatos a criarem seus sites mais facilmente e ao mesmo tempo compatível com a maioria dos navegadores (isto se os usuários atualizarem suas máquinas). 

Spring MVC 3 na Prática com JPA 2

Por Edson Gonçalves

Fonte http://imasters.uol.com.br/artigo/17935

Olá, pessoal, tudo bom?

Este é o segundo artigo da série Spring MVC 3.0. Desta vez iremos trabalhar com a JPA em conjunto com o framework Spring MVC. Como sempre, dúvidas e críticas são bem-vindas.

Para este artigo, vamos utilizar o Tomcat 7.0, ainda em beta. Para baixar o binário do Tomcat 7, vá até o endereço http://tomcat.apache.org/.

O banco de dados utilizado será o MySQL. Você pode baixar a versão 5.1, utilizada no artigo, aqui.

O ambiente de trabalho

A própria empresa responsável pelo Spring Source, divisão da VMware, possui uma ferramenta completa, criada sobre a plataforma Eclipse, chamada de SpringSource Tools Suite. Para baixar o SpringSource Tools Suite, clique aqui, preencha o formulário e faça o Download. Como a ferramenta possui uma opção de instalador, use-a como facilitador se desejare. Na própria página onde baixar o arquivo, haverá a explicação da instalação em cada plataforma, em Installation Instructions.

Criando o projeto

Na view Package Explorer, com o botão direito do mouse, selecione New>Spring Template Project no menu de contexto.

Na caixa de diálogo New Template Project, selecione Spring MVC Project e clique no botão Next.

Ao aparecer a caixa de diálogo Import, clique no botão Yes para permitir que o projeto faça o download das bibliotecas do Spring MVC. No segundo projeto que criar, não haverá necessidade desse download. Falaremos mais adiante sobre esse download e como ele ocorre.

Após o download das bibliotecas, prosseguiremos na criação do projeto. Coloque o nome do seu projeto em Project name e o pacote principal abaixo. Confirme no botão Finish.

Figura 4  definição do nome do projeto e pacote principal

Definição do nome do projeto e pacote principal

O assistente criará, em sua conclusão, um projeto com uma estrutura básica, contendo uma classe, página e arquivos de configurações do framework Spring MVC, como mostra na Figura 5.

Figura 5  estrutura inicial do projeto gerado

Estrutura inicial do projeto gerado

Alterando o projeto base gerado pelo assistente

Além dos arquivos contidos para a execução do projeto, temos o pom.xml, o que denota que o projeto é gerado sobre a estrutura do Maven.

Na view Package Explorer, se expandirmos Maven Dependencies, veremos as bibliotecas que o projeto necessita para ser executado. Nesse momento, o projeto está funcionando tal como foi gerado pelo assistente.

Para compreendermos o que foi gerado, vejam o primeiro artigo que escrevi sobre o Spring MVC, no qual explico a base do framework.

Entretanto, não vamos utilizar alguns dos arquivos criados. Selecione os seguintes diretórios e arquivos do projeto e os remova:

  • WelcomeController.java
  • WelcomeControllerTests.java
  • spring/
  • views/
  • urlrewrite.xml

Adicionando outras bibliotecas ao projeto utilizando o Maven

Embora boa parte das bibliotecas que precisamos no projeto já estejam disponíveis, precisamos adicionar a biblioteca JDBC do MySQL e as do Hibernate para trabalharmos com a JPA 2.

Abra o arquivo pom.xml, encontrado na view Package Explorer. No canto superior do lado direito, temos o ícone Show Advanced Tabs. Vamos exibir, ao clicar neste ícone, novas tabs que permitirão configurar novos repositórios.

Figura 7  exibindo tabs avançadas do editor visual para o arquivo pom.xml

Exibindo tabs avançadas do editor visual para o arquivo pom.xml

Adicionando um repositório

Na aba Repositories, clique no botão Create. Preencha com JBoss Repo em Id e http://repository.jboss.com/maven2. Esse repositório será necessário para obtermos a última versão do Hibernate, importante para nosso projeto.

Criando propriedades

Caso você não conheça o Maven ainda, já deve ter desconfiado que informamos um endereço para baixarmos as bibliotecas. Entretanto, quais desejamos?

Na aba Overview, em Properties, clique no botão Create. Na caixa de diálogo Add property, preencha como na figura abaixo.

Figura 9  criação da property da versão do hibernate

Criação da property da versão do Hibernate

Adicione outra property preenchendo o diálogo assim:

Figura 10  criação da property da versão da jpa

Criação da property da versão da JPA

Por fim, adicione mais uma property e preencha conforme indicado:

Figura 11  criação da property da versão da biblioteca jdbc do mysql

Criação da property da versão da biblioteca JDBC do MySQL

Criando as dependências

As propriedades foram definidas para informar qual versão desejamos utilizar das bibliotecas que o Maven deverá baixar. Entretanto, precisamos configurar as dependências.

Na aba Dependencies, clique no botão Create e preencha conforme a ilustração:

Figura 12  a dependência do hibernate

A dependência do Hibernate

Crie uma nova dependência e configure assim:

Figura 13  - a dependência da api jpa 2.0

A dependência da API JPA 2.0

Faça o mesmo processo preenchendo conforme abaixo:

Figura 14  a dependência da biblioteca jdbc do mysql

A dependência da biblioteca JDBC do MySQL

E, para a parte de transações do Spring, configure a dependência desta maneira:

Figura 15  a dependência da biblioteca para transações do spring framework

A dependência da biblioteca para transações do Spring Framework

Para trabalhar com banco de dados no Spring, configure a dependência conforme indicado:

Figura 16  a dependência da biblioteca jdbc do spring framework

A dependência da biblioteca jdbc do Spring Framework

Como estamos trabalhando com a JPA, o  Spring precisa da dependência que configuramos no Maven:

Figura 17  a dependência da biblioteca orm do spring framework

A dependência da biblioteca orm do Spring Framework

Ao salvar o arquivo, automaticamente o Maven entrará em ação trazendo as bibliotecas faltantes para o seu projeto. Vemos isso na view Console.

Nota: Detalhes de como o Maven funciona não serão mostrados neste artigo. É importante lembramos que o objetivo não é ensinar a trabalhar com Maven, seja através do arquivo pom.xml ou pelo Eclipse IDE.

Um CRUD com Spring MVC utilizando JPA 2.0

O projeto neste artigo será baseado em apenas uma entidade, suficiente mostrar a você a integração entre as duas tecnologias no desenvolvimento.

Iremos agora modificar o projeto criado automaticamente pelo assistente.

A entidade Contato

Teremos para o exemplo apenas uma entidade, chamada de Contato. Essa entidade trabalhará com uma tabela contato, que possui quatro atributos, sendo o atributo id o único que será gerado automaticamente. A Listagem 1 exibe a entidade que será usada no exemplo.

Listagem 1. A entidade Contato.

package br.com.integrator;

import javax.persistence.*;

@Entity

@Table(name = "contato")

public class Contato {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

@Column(name = "id")

private Long id;

private String nome;

private String email;

private String telefone;

//getters and setters

}

Para fazê-la, clique com o direito do mouse sobre o pacote br.com.integrator e selecione, no menu de contexto, o item New>Class.

Acessando os dados

O acesso aos dados é feito pelo padrão DAO (Listagem 2), com a adição de anotações do Spring Framework. No princípio, adicionamos a anotação @Repository(“contatoDao”), que indica ao Spring Framework que se trata de um DAO. Veremos mais a respeito adiante, na configuração final do Spring.

Utilizamos a anotação @Transactional, para fazer o controle transacional e a anotação @PersistenceContext, permitindo assim com que o Spring injete um EntityManager no serviço quando instanciado. Essa anotação pode ser colocada no atributo ou método setter. Com a essa injeção, temos um comportamento similar ao oferecido pelo EJB 3, incluindo transações, só que sem a necessidade de um contêiner EJB para isso.

Para criar a classe da Listagem 2, crie uma nova classe e coloque o pacote br.com.integrator.dao e preencha o nome da classe como ContatoDAO.

Figura 19  criação da classe contatodao

Criação da classe ContatoDAO

Listagem 2. A classe ContatoDAO.

package br.com.integrator.dao;

import java.util.List;

import javax.persistence.EntityManager;

import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Repository;

import org.springframework.transaction.annotation.Transactional;

import br.com.integrator.Contato;

@Repository("contatoDao")

public class ContatoDAO{

protected EntityManager entityManager;

public ContatoDAO() {

}

@PersistenceContext

public void setEntityManager(EntityManager entityManager) {

this.entityManager = entityManager;

}

public Contato find(Long id) {

return entityManager.find(Contato.class, id);

}

@Transactional

public void persist(Contato contato) {

entityManager.persist(contato);

}

@Transactional

public void merge(Contato contato) {

entityManager.merge(contato);

}

@Transactional

public void remove(Contato contato) {

entityManager.remove(contato);

}

@SuppressWarnings("unchecked")

public List<Contato> findAll() {

return entityManager.createQuery("SELECT c FROM Contato c").getResultList();

}

}

Controlando como o aplicativo funciona

A classe ContatoController, que será criada no pacote br.com.integrator.web, exibida na Listagem 3, lida com as requisições do cliente, controlando o rumo que será dado na chamada a uma determinada view.

Listagem 3. A classe ContatoController.

package br.com.integrator.web;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.ui.ModelMap;

import org.springframework.web.bind.annotation.*;

import br.com.integrator.dao.ContatoDAO;

import br.com.integrator.Contato;

@Controller

@RequestMapping("/contato/**")

public class ContatoController {

@Autowired

private ContatoDAO contatoDao;

@RequestMapping(value = "/contato/{id}", method = RequestMethod.GET)

public String show(@PathVariable("id") Long id, ModelMap modelMap) {

modelMap.addAttribute("contato", contatoDao.find(id));

return "contato/show";

}

@RequestMapping(value = "/contato", method = RequestMethod.GET)

public String list(ModelMap modelMap) {

modelMap.addAttribute("contatos", contatoDao.findAll());

return "contato/list";

}

@RequestMapping(value = "/contato/{id}", method = RequestMethod.DELETE)

public String delete(@PathVariable("id") Long id) {

contatoDao.remove(contatoDao.find(id));

return "redirect:/contato";

}

@RequestMapping(value = "/contato/form", method = RequestMethod.GET)

public String form(ModelMap modelMap) {

modelMap.addAttribute("contato", new Contato());

return "contato/create";

}

@RequestMapping(value = "/contato", method = RequestMethod.POST)

public String create(@ModelAttribute("contato") Contato contato) {

contatoDao.persist(contato);

return "redirect:/contato";

}

@RequestMapping(value = "/contato/{id}/form", method = RequestMethod.GET)

public String updateForm(@PathVariable("id") Long id, ModelMap modelMap) {

modelMap.addAttribute("contato", contatoDao.find(id));

return "contato/update";

}

@RequestMapping(method = RequestMethod.PUT)

public String update(@ModelAttribute("contato") Contato contato) {

contatoDao.merge(contato);

return "redirect:/contato";

}

}

Introduzida na versão do Spring MVC 2.5, podemos declarar uma classe como sendo a controller do framework simplesmente utilizando a anotação @Controller, de org.springframework.stereotype.Controller. Essa anotação permite que o Spring faça seu “scan” automaticamente através do elemento <context:component-scan>.

Com a anotação @RequestMapping, encontrada após @Controller, definimos o caminho HTTP que será utilizado na aplicação, sendo mapeada pela classe. Na prática, todas as chamadas na aplicação contendo o “/contato/*” serão analisadas pela classe controller.

O suporte a RESTful foi completamente adicionado no Spring MVC 3, onde determinamos o seu comportamento através também da anotação @ResquestMapping. Agora, o servlet Spring Dispatcher suporta os seguintes métodos HTTP: GET, HEAD, POST, PUT e DELETE.

Para efeitos comparativos, se colocarmos cada um dos métodos HTTP ao lado de um simples aplicativo que executa as quatro operações básicas (CRUD), teríamos o GET como sendo o READ, o POST como CREATE, o PUT como UPDATE e o DELETE como por ele mesmo.

Infelizmente, os navegadores não compreendem nada além de GET e POST em formulários HTML. Ao declarar no formulário do Spring MVC que o método de submissão é o DELETE, por exemplo, este se transformará em um método POST, para que o navegador entenda, só que contendo um campo oculto com o valor DELETE. Infelizmente esse feito não é mágico, e no Spring MVC essa característica só é possível porque configuramos o filtro org.springframework.web.filter.HiddenHttpMethodFilter no arquivo web.xml(veja a Listagem 4).

Ao submeter o formulário, a anotação @ResquestMapping verifica o caminho e o método submetido. Imagine que @ResquestMapping recebe uma chamada HTTP com o caminho “/contato/1”, seria apenas uma visualização do contato número 1 se RequestMethod.DELETE não fosse acionado, disparando automaticamente o método delete(), que tem como objetivo remover o contato. Essa remoção é feita pelo remove() do DAO.

Através de templates URI, a anotação @PathVariable determina a variável que será recebida e transmitida para o método em questão. Se quisermos excluir um determinado contato, enviamos ao navegador o caminho “/contato/1”, mas que será traduzido como “contato?id=1”. Como parâmetro, a variável pode ser convertida para um determinado tipo em sua captura, assim como renomeada.

A conclusão de cada operação no controller pode ser feita através de um redirecionamento, enviando a string “redirect:/caminho” ou simplesmente retornando o caminho que deseja exibir.

A configuração do web.xml

O arquivo web.xml precisa de alguns ajustes, uma vez que ele já possui configurações iniciais para trabalhar com o Spring MVC. A Listagem 4 exibe o arquivo web.xml na íntegra.

Listagem 4. O web.xml.

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<display-name>SpringMVC</display-name>

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

<servlet>

<servlet-name>ContatoManager</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>ContatoManager</servlet-name>

<url-pattern>/</url-pattern>

</servlet-mapping>

<servlet-mapping>

<servlet-name>default</servlet-name>

<url-pattern>/static/*</url-pattern>

</servlet-mapping>

<!-- habilitar o suporte REST do Spring 3.0 -->

<filter>

<filter-name>httpMethodFilter</filter-name>

<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>

</filter>

<!-- Permite colocar um campo oculto para PUT e DELETE -->

<filter-mapping>

<filter-name>httpMethodFilter</filter-name>

<servlet-name>ContatoManager</servlet-name>

</filter-mapping>

<filter>

<filter-name>OpenEntityManagerInViewFilter</filter-name>

<filter-class>

org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter

</filter-class>

</filter>

<filter-mapping>

<filter-name>OpenEntityManagerInViewFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<session-config>

<session-timeout>10</session-timeout>

</session-config>

<welcome-file-list>

<welcome-file>index.jsp</welcome-file>

</welcome-file-list>

</web-app>

Para o Spring MVC funcionar, utilizamos o servlet org.springframework.web.servlet.DispatcherServlet, configurado no arquivo web.xml da aplicação. Por padrão, o Spring olha beans em arquivos cujo começo possui o mesmo nome do Servlet configurado, seguido de -servlet.xml. Para melhor entendimento, o nome ContatoManager, dado no elemento <servlet-name/>, fará com que o Spring procure por um arquivo chamado ContatoManager-servlet.xml.

Evidentemente ele não é o único item que deve ser configurado no arquivo, já que, se pretendemos trabalhar com REST, como já foi citado anteriormente, precisamos adicionar o filtro pela classe org.springframework.web.filter.HiddenHttpMethodFilter.

Para trabalhar com a JPA, utilizamos o filtro org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter, do Spring. Entretanto, deixarei para falar sobre esse filtro em outra ocasião.

O arquivo persistence.xml

A Listagem 5 mostra o arquivo persistence.xml, que configura como provider o Hibernate.  Esse arquivo deve ser criado dentro do diretório META-INF. Esse diretório será criado em src/main/Java. Veja como ficará em seu projeto:

Figura 20  localização do arquivo persistence.xml dentro de meta-inf

Localização do arquivo persistence.xml dentro de META-INF

Listagem 5. Configuração do arquivo persistence.xml.

<?xml version="1.0" encoding="UTF-8"?>

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/persistence

http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

<persistence-unit name="ContatoPU" transaction-type="RESOURCE_LOCAL">

<class>br.com.integrator.Contato</class>

<properties>

<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/springmvc"></property>

<property name="javax.persistence.jdbc.user" value="edson"></property>

<property name="javax.persistence.jdbc.password" value="integrator"></property>

<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"></property>

<property name="hibernate.show_sql" value="true" />

<property name="hibernate.format_sql" value="true" />

<property name="hibernate.hbm2ddl.auto" value="create"/>

</properties>

</persistence-unit>

</persistence>

Configurando o Spring

Revisando até o momento em que o criamos, temos um DAO simples que se comunica com o banco de dados através da JPA, utilizando o Hibernate como provider.

Esse DAO será executado pelo Controller do Spring MVC, também já configurado.

Para trabalhar com todas essas informações, dividiremos as configurações em dois arquivos, separando suas responsabilidades.

O primeiro arquivo, chamado de applicationContext.xml (Listagem 6), será o utilizado para a trabalhar com a injeção de dependências na classe DAO, lidando com as características da JPA. Esse arquivo deve ser criado dentro do diretório WEB-INF.

Para criá-lo, clique com o direito do mouse em src/main/webapp/WEB-INF e selecione New>Spring Bean Configuration File no menu de contexto.

Na caixa de diálogo Create a new Spring Bean Definition file, coloque o nome do arquivo de applicationContext e clique no botão Next.

Na segunda etapa, mantenha o beans e mantenha selecionado o item XSD.

Figura 22  seleção do namespace beans

Seleção do namespace beans

Ainda na segunda etapa, mantenha o context e mantenha selecionado o item XSD.

Figura 23  seleção do namespace context

Seleção do namespace context

A última opção que selecionaremos na segunda etapa será o tx; e mantenha selecionado o item XSD. Confirme no botão Finish.

Figura 24  seleção do namespace tx

Seleção do namespace tx

Caso tenhamos esquecido de selecionar algum namespace, não tem importância, pois ao finalizar o assistente, o editor do arquivo de configuração do Spring se abre. Nesse caso, vamos adicionar um último namespace. Clique na aba Namespaces e marque o namespace mvc e selecione o XSD como mostrado abaixo.

Figura 25  seleção do namespace mvc

Seleção do namespace mvc

O conteúdo completo do arquivo applicationContext.xml está na Listagem 6.

Listagem 6. Configuração do arquivo applicationContext.xml.

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

<property value="ContatoPU" />

</bean>

<context:component-scan base-package="br.com.integrator"/>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">

<property name="entityManagerFactory" ref="entityManagerFactory"/>

</bean>

<mvc:annotation-driven/>

<tx:annotation-driven />

<context:annotation-config />

</beans>

No Spring MVC, para determinar a classe controladora, utilizamos a anotação @Controller. Entretanto, para que seja possível detectar essa anotação, o Spring utiliza o elemento <context:component-scan />, no qual indicamos o pacote em que ele pode verificar. Esse recurso é chamado de Classpath scanning, que permite ao Spring ler as classes encontradas no pacote indicado da aplicação em busca das que estão anotadas. Isso evita que tenhamos de declarar essas classes no XML.

Ao fazer esse “scanning”, as classes são passadas por um filtro e então a definição de um bean é criada para cada uma delas. Evidentemente que esse filtro é determinado pelas anotações, nas quais não existem apenas as anotações que utilizamos neste exemplo, mas de outras mais que temos como referencia para o framework: @Component, @Service, @Controller e @Repository (que foi introduzida no Spring 2.0). Você pode também criar suas próprias anotações e filtros para declarar os componentes.

Para o Spring trabalhar com a JPA, na qual a execução ocorre em ambientes Java EE, utilizamos a factory org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean:

<bean

class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

<property name="persistenceUnitName" value="ContatoPU" />

</bean>

Com a propriedade de LocalContainerEntityManagerFactoryBean, especificamos o nome da persistence unit do arquivo persistence.xml. É nesse arquivo que temos as configurações de acesso ao banco de dados pela JPA para realizar as operações de persistência.

Para a configuração do controle transacional em uma aplicação baseada no Spring, é necessário declarar um gerenciador que, nesse caso, será a classe org.springframework.orm.jpa.JpaTransactionManager. Essa classe é utilizada para trabalhar com a JPA, independente de provedor ORM. A declaração da classe é ilustrada no trecho a seguir:

<bean

class="org.springframework.orm.jpa.JpaTransactionManager">

<property name="entityManagerFactory" ref="entityManagerFactory" />

</bean>

JpaTransactionManager precisa de qualquer implementação de javax.persistence.EntityManagerFactory para colaborar com EntityManager produzido pela fabrica, para conduzir transações. A classe JpaTransactionManager é recomendada para aplicações que utilizam apenas uma EntityManager.

Para que não tenhamos que fazer injeção de dependência do EntityManager em todos os nossos DAOs, utilizamos o elemento <context:annotation-config />, que procura todas as classes anotadas com @PersistenceContext, @Autowired (que veremos mais adiante), entre outros, e faz a injeção de dependência automaticamente.

Por termos configurado as transações no DAO, por meio da utilização da anotação @Transactional, o elemento <tx:annotation-driven> foi utilizado.

Como se não bastasse, temos também a parte do Spring MVC, que utiliza o elemento mvc:annotation-driven />, permitindo enviar as requisições das classes que possuem a anotação @Controller.

Configurando o Spring MVC

O segundo arquivo, com o nome de ContatoManager-servlet.xml (Listagem 7), será o responsável por configurar o caminho das views e a tecnologia empregada no projeto do Spring MVC.

Para criá-lo, clique com o direito do mouse sobre o diretório src/main/webapp/WEB-INF e selecione New>Spring Bean Configuration File no menu de contexto.

Na caixa de diálogo Create a new Spring Bean Definition file, coloque o nome do arquivo de ContatoManager-servlet e clique no botão Next.

Na segunda etapa, mantenha apenas o item beans selecionado, como mostrado na Figura 27. Finalize o assistente pelo botão Finish.

Figura 27  seleção do namespace beans

Seleção do namespace beans

A Listagem 7 exibe, na íntegra, o conteúdo do arquivo ContatoManager-servlet.xml.

Listagem 7. Configuração do arquivo ContatoManager-servlet.xml.

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<property value="/WEB-INF/jsp/"/>

<property value=".jsp"/>

</bean>

</beans>

O Spring MVC possui um suporte a inúmeros tipos de views, utilizando diversos tipos de tecnologias, como JSP, FreeMarker, JasperReports, Velocity, XML, XSLT e outros. Quando vamos criar um projeto Spring MVC, podemos utilizar uma ou diversas ao mesmo tempo, o que significa que é possível apresentar uma página em HTML gerada pelo JSP contendo os dados vindos do banco de dados através do uso do Spring MVC e também um XML contendo os mesmos dados, com uma pequena alteração de extensão no navegador.

Com a classe org.springframework.web.servlet.view.InternalResourceViewResolver, pré-fixamos o caminho das páginas em “/WEB-INF/jsp/” e damos o sufixo, sendo “.jsp”. Para o conteúdo das páginas, temos InternalResourceViewResolver, uma subclasse de UrlBasedViewResolver, que suporta JSTL e que utilizaremos em nossas views.

Atenção: Como boa prática recomendada pelo Spring, coloque as páginas JSP dentro do diretório WEB-INF, impedindo assim seu acesso direto através da URL.

As views

Criaremos agora três páginas que representarão nosso CRUD. Essas páginas serão criadas dentro de um diretório chamado contato, que ficará dentro de jsp em WEB-INF. Os diretórios jsp e contato ainda não foram criados. Para criá-los, clique com o direito do mouse sobre src/main/webapp/WEB-INF e selecione New>Folder no menu de contexto.

O formulário de cadastro

Se preferir, mude a perspectiva do Eclipse para Java EE, assim será possível clicar com o direito do mouse sobre o diretório e selecionar, no menu de contexto, o item New>JSP File. O assistente de criação de páginas JSP pode lhe ajudar com um template Basico. Por fim, dê o nome de create.jsp no arquivo e coloque o conteúdo similar ao mostrado na Listagem 8.

Listagem 8. A página create.jsp.

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<style type="text/css" media="screen">

@import url("<c:url value="/static/styles/style.css"/>");

</style>

<title>Cadastrar</title>

</head>

<body>

<div id="wrap">

<div>

<%@ include file="/menu.jsp" %>

</div>

<div>

<div>

<c:url var="url" value="/contato" />

<form:form action="${url}" method="POST" modelAttribute="contato">

<div>

<label for="nome">Nome:</label>

<form:input cssStyle="width:250px" maxlength="30" path="nome" size="30"/>

</div>

<br/>

<div>

<label for="email">Email:</label>

<form:input cssStyle="width:250px" maxlength="30" path="email" size="30"/>

</div>

<br/>

<div>

<label for="telefone">Telefone:</label>

<form:input cssStyle="width:250px" maxlength="30" path="telefone" size="20"/>

</div>

<br/>

<div class="submit">

<input value="Criar Contato"/>

</div>

</form:form>

</div>

</div>

</div>

</body>

</html>

Podemos ter uma idéia de como ficará a página create.jsp através da figura abaixo:

Figura 29  a página create.jsp

A página create.jsp

Analisando o web.xml, veremos o elemento <servlet-mapping/>, que define onde a aplicação encontrará os conteúdos estáticos do aplicativo. O Servlet default, utilizado nesse caso, pertence às configurações padrão do Tomcat, responsável por servir conteúdos estáticos de aplicações web. Mesmo que seus arquivos não estejam em um diretório com esse nome, é necessário acrescentá-lo como parte do caminho. Isso inclui imagens e folhas de estilo (podem ser obtidos no projeto completo encontrado no final para download).

Para criar essas páginas, utilizamos tags da biblioteca JSTL e tags do próprio Spring. No caso do Spring, as tags <form/> possibilitam que tenhamos um formulário ligado ao controller. Para utilizar essas tags, devemos acrescentar a seguinte taglib:

<%@ taglib prefix=”form” uri=”http://www.springframework.org/tags/form&#8221; %>

Na construção dos formulários para inserir e atualizar, utilizamos a tag <form:form/> que possui um atributo modelAttribute,  ligando o formulário ao parâmetro do método que executa sua ação. O atributo method indica qual o tipo de ação será feita no controller.

A tag <form:input/> possui o atributo path com o valor correspondente aos atributos existentes no bean Contato.

A página que lista todos os cadastros e permite a exclusão

Para a listagem de todos os cadastros efetuados, criaremos uma página chamada list.jsp, contendo as mesmas informações existentes na Listagem 9.

Junto à listagem, teremos a possibilidade de excluir o cadastro diretamente por essa página.

Listagem 9. A página list.jsp.

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<style media="screen">

@import url("<c:url value="/static/styles/style.css"/>");

</style>

<title>Listar</title>

</head>

<body>

<div>

<div id="menu">

<%@ include file="/menu.jsp" %>

</div>

<div id="main">

<div>

<c:if test="${not empty contatos}">

<table width="600px">

<tr>

<thead>

<th>Id</th>

<th>Nome</th>

<th>E-mail</th>

<th>Telefone</th>

<th>Atualizar</th>

<th>Excluir</th>

</thead>

</tr>

<c:forEach items="${contatos}" var="contato">

<c:url var="url" value="/contato/${contato.id}" />

<tr>

<td>${contato.id}</td>

<td>${contato.nome}</td>

<td>${contato.email}</td>

<td>${contato.telefone}</td>

<td>

<form:form action="${url}/form" method="GET">

<input alt="Atualizar Contato" src="<c:url value="/static/images/update.png"/>" title="Atualizar Contato" value="Atualizar Contato"/>

</form:form>

</td>

<td>

<form:form action="${url}" method="DELETE">

<input alt="Excluir Contato" src="<c:url value="/static/images/delete.png"/>" title="Excluir Contato" value="Excluir Contato"/>

</form:form>

</td>

</tr>

</c:forEach>

</table>

</c:if>

<c:if test="${empty contatos}">Não há contatos cadastrados.</c:if>

</div>

</div>

</div>

</body>

</html>

O Spring MVC gera um Map através de sua classe org.springframework.ui.ModelMap, na qual capturamos os valores retornados pelo método findAll(), de ContatoDAO. Esse Map é capturado pela view, no clássico esquema definido pelo MVC.

No caso da listagem de contatos, esse Map, definido como contatos no método list(), de ContatoController, é varrido por um loop criado pela tag JSTL <c:forEach /> no seguinte trecho:

<c:forEach items=”${contatos}” var=”post”>

Na listagem dos contatos, em uma das tags <form:form/>, vemos em um de seus atributos method o valor DELETE, definido como a ação de exclusão de contatos.

Como os navegadores não reconhecem o envio de formulários além dos métodos POST e GET, precisamos de uma ajuda do Spring Framework para fazer a operação DELETE. O que o Spring MVC fará é traduzir o valor do atributo dessa tag, na geração do HTML, da seguinte forma:

<form method=”post”>

<input type=”hidden” value=”DELETE”/>

Observe que ele criou uma tag oculta HTML na renderização da página com um nome _method e com o valor DELETE. Essa simples adição permitirá a ação de excluir pela classe PostController.

A página de atualização de dados

A última página que teremos no CRUD é a de atualizar (update.jsp), similar ao de adicionar dados, exceto pelo fato de receber os dados vindos do banco de dados para serem exibidos.

Listagem 10. A página update.jsp.

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<style type="text/css" media="screen">

@import url("<c:url value="/static/styles/style.css"/>");

</style>

<title>Atualizar</title>

</head>

<body>

<div id="wrap">

<div>

<%@ include file="/menu.jsp" %>

</div>

<div>

<div>

<c:url var="url" value="/contato/${contato.id}" />

<form:form action="${url}" method="PUT" modelAttribute="contato">

<div>

<label for="nome">Nome:</label>

<form:input cssStyle="width:250px" maxlength="30" path="nome" size="30"/>

</div>

<br/>

<div>

<label for="email">Email:</label>

<form:input cssStyle="width:250px" maxlength="30" path="email" size="30"/>

</div>

<br/>

<div>

<label for="telefone">Telefone:</label>

<form:input cssStyle="width:250px" maxlength="30" path="telefone" size="20"/>

</div>

<br/>

<div class="submit">

<input value="Atualizar Contato"/>

</div>

<form:hidden path="id"/>

</form:form>

</div>

</div>

</div>

</body>

</html>

Similar ao que ocorre com a listagem de contatos, temos no formulário da página de atualização o valor PUT para o atributo method. Novamente, o Spring Framework irá gerar um campo oculto, em HTML, contendo essa informação e transmitindo ao navegador o HTML como ele já o conhece.

As páginas que não fazem parte do CRUD

O menu e a página inicial não fazem parte do CRUD e, portanto, serão apenas apresentadas aqui com seus códigos para completar o exemplo.

A página index.jsp deverá ser criada em  webapps:

Listagem 11. A página index.jsp.

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<link href="<c:url value="/static/styles/style.css"/>" rel="stylesheet" />

<title>Principal</title>

</head>

<body>

<div id="wrap">

<div>

<%@ include file="/menu.jsp" %>

</div>

<div>

<div>

Aplicação CRUD criada utilizando o Spring MVC 3.0 com suporte a REST.

</div>

</div>

</div>

</body>

</html>

Assim como index.jsp, crie o menu.jsp em webapps.

Listagem 12. A página menu.jsp.

<ul>

<li>

<h2>Contato</h2>

<ul>

<li><a href="<c:url value="/contato"/>">Ver todos</a></li>

<li><a href="<c:url value="/contato/form"/>">Novo Contato</a></li>

</ul>

</li>

</ul>

Figura 32  visão geral de todos os arquivos utilizados na geração do projeto

Visão geral de todos os arquivos utilizados na geração do projeto

O projeto para download

Clique aqui para baixar o projeto completo como feito até o momento.

Considerações finais

Agora que aprendemos a fazer um CRUD com o Spring MVC, podemos criar projetos mais complexos. Caso esteja com pressa de aprender algo mais complexo, a revista JavaMagazine #78 publicou, alguns meses atrás, um artigo meu com o Spring MVC 3 na criação de um blog, passo a passo.

DANRESA Consultoria de Informática, há 10 anos transformando conhecimento e tecnologia em soluções de negócios.

Há 10 anos no mercado, a DANRESA é uma Consultoria de Informática que agrega valores aos negócios de seus clientes por meio de consultoria estratégica e soluções completas envolvendo produtos e serviços de TI.

Hoje são mais de 100 clientes atendidos pela DANRESA com qualidade e eficiência em todo o Brasil.

A DANRESA identifica como as tecnologias de TI existentes no mercado podem ajudar seus clientes a reduzir custos, aumentar a produtividade empresarial, e aumentar seu potencial competitivo, destacando-os de seus concorrentes.

A DANRESA é uma empresa parceira Microsoft Certified e oferece aos seus clientes:

 – Outsourcing, Outtasking e Multisourcing de TI

– Desenvolvimento de Sistemas Client-Server e Web, envolvendo Portais Corporativos, Lojas Virtuais, B2B, B2C, EDI, Integrações de Sistemas. Projetos, Alocações e Fábrica de Software.

– Soluções de Infra-Estrutura, Segurança e Rede, VOIP.

– Inteligência Corporativa ( BI ), SOA, BPM, Colaboração

– Data Management Solutions, Information Worker Solutions, Mobility Solutions, Security Solutions, Licensing Solutions, e-Learning Solutions, Security Solutions.

 Solicite uma visita e/ou um mapeamento de sua Infra-Estrutura de TI com um de nossos consultores e descubra como a DANRESA pode ajudar a sua empresa a alcançar os resultados corporativos desejados com as Soluções Inovadoras de TI da DANRESA.

Saiba mais em http://www.danresa.com.br

Ou ligue para 55 11 4452-6450 e contate um de nossos gerentes comerciais.

Deploy an ASP.NET Form to a workflow

Published: 12 Jul 2010
By: Manning Publications

This article, taken from the book SharePoint 2010 Workflows in Action, shows you how easy it is to deploy an ASP.NET form to a workflow.

Contents [hide]

About the book

This is the 9th chapter of the book SharePoint 2010 Workflows in Action. It has been published with the exclusive permission of Manning.
Written by: Phil Wicklund
Pages: 400
Publisher: Manning
ISBN-10: 9781935182719

Get 30% discountDotNetSlacker readers can get 30% off the full print book or ebook at www.manning.com using the promo code dns30 at checkout.

ASP.NET forms can be a bit tricky to develop, but they’re easy to deploy. You add the form to a workflow, SharePoint 2010 packages everything up neat and tidy, and all that’s left for you to do is to deploy the project. Once you associate the workflow to a list or initiate the workflow on an item, SharePoint will recognize and use your custom ASP.NET form! The process takes seconds!

Once deployed, you’ll notice that the form is blank. Deployment was easy, but now it’s time to put our developer hat on and add some controls to that form, so users can pass data between the form and the workflow. To illustrate this process, we’ll create a generic initiation form. (Along the way, I’ll point out differences for association forms.)

Getting started

Let’s get started by creating a new sequential workflow project called TestASPNETWorkflowForms. Create a list workflow, and bind it to a list of your choice with the project provisioning wizard. After the project has been created, right-click on Workflow1, and choose Add, New Item. The new item dialog will appear (figure 1). Select a Workflow Initiation Form.

Figure 1: ASP.NET forms are extremely easy to integrate into a Visual Studio workflow. Simply right-click the workflow and add a new item.

After adding the form, SharePoint displays an ASP.NET HTML view of the form (figure 2). This auto-generated form has a button that’s wired and ready to go. To view the code behind the form, right-click it in the Solution Explorer and choose View Code. You’ll notice four auto-generated methods

  • Page_Load: Use this method to set default values for the fields on your form.
  • GetInitiationData or GetAssociationData: Our workflow calls this method to retrieve the values the user enters into the form. Simply return a string in this method that contains a serialized class with the form data stored in it. Then, on the workflow side of things, we can deserialze this class and the workflow can do something with the data.
  • StartWorkflow_Click: Submits the form.
  • Cancel_Click: Cancels the form

There’s not much to worry about with these methods because they’re complete as is. Usually, you won’t need to alter these methods, but they’re available, if you need to.

Figure 2: The auto-generated ASP.NET form has a button and controls wired and ready to go.

Adding Controls

Return to the ASP.NET HTML view (if necessary), so we can add a few ASP.NET controls. Inside the PlaceHolderMain content placeholder, add a few text boxes. We will use these text boxes to allow the user to enter information. To ship the user input values to the workflow, we’ll use the GetInitiationData method to return a string containing the data. We don’t want to pass just any string, we need a string that represents a serialized class that both the form and the workflow can instantiate and serialize/deserialize. To this purpose, right click Workflow1, choose Add and then select New Item. Choose a class file and then name the class InitiationFormParameters. Make the class public, and add two public strings, one for each parameter in the initiation form.

1.public class InitiationFormParameters
2.{
3.    public string InitiationParameter1;
4.    public string InitiationParameter2;
5.}

Back in the code behind of the ASP.NET form, find the GetInitiationData method. Add the code in Listing 1 to this method.

Listing 1: GetInitiationData method

01.string initdata = string.Empty;
02. 
03.InitiationFormParameters data = new InitiationFormParameters();        
04.data.InitiationParameter1 = InitParameter1.Text;                   
05.data.InitiationParameter2 = InitParameter2.Text;                   
06. 
07.using (StringWriter writer = new StringWriter())
08.{
09.    XmlSerializer s = new XmlSerializer(typeof(InitiationFormParameters));
10.    s.Serialize(writer, data);                         
11. 
12.    initdata = writer.ToString();
13.}
14. 
15.return initdata;

This code first creates an instance of our class and assigns properties to the user input values stored in the form . Next, it serializes that class into a string with a StringWriter, and then returns that string.

Our workflow calls the GetInitiationData method and loads the string into a property of the OnWorkflowActiviated activity called InitializationData (or AssociationData). Next, we must deserialize the stored string in InitializationData into a class the workflow can use. To do so, right-click the OnWorkflowActivated activity and choose Generate Handlers. Then, replace the onWorkflowActivated1_Invoked method with the code in Listing 2.

Listing 2 onWorkflowActivated1_Invoked method

01.string param1;
02.string param2;
03.  
04.private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
05.{
06.    XmlSerializer serializer = new XmlSerializer(typeof(InitiationFormParameters));
07. 
08.    XmlTextReader reader = new XmlTextReader(new System.IO.StringReader(onWorkflowActivated1.WorkflowProperties.InitiationData));
09. 
10.    InitiationFormParameters initiationFormData = (InitiationFormParameters)serializer.Deserialize(reader);
11. 
12.    param1 = initiationFormData.InitiationParameter1;              
13.    param2 = initiationFormData.InitiationParameter2;
14.}

This code retrieves the user input data so the workflow can then perform some action on that data. The first thing we want to do is read the string out of the InitiationData property (or AssociationData) into an XmlTextReader. Then, we want to deserialize that XML into a new object that is the same type the string was serialized into (in this case the InitiationFormParameters object). After we have our object, we can start assigning some global variables or take other actions.

Our last step is to make sure everything is working, so add a LogToHistoryListActivity activity below the OnWorkflowActivated activity. We can use this history logger to render our form values on the workflow status page. After the LogToHistoryActivity activity is added, right-click it and choose Generate handlers. In the method that was generated, add the following code to display the user input values:

1.logToHistoryListActivity1.HistoryDescription = "Param1: " + param1 + " Param2: " + param2;

With this activity logging our form parameters, we can start testing. First, build and deploy the project. If you hadn’t already associated the workflow to a list, do so now. Otherwise, start the workflow on an item in the list. You should see our custom ASP.NET initiation form shown in figure 3.

Figure 3: Our initiation form will prompt the user for pertinent information when the workflow starts.

Enter some values and submit the form. The form will display a status of completed. Click the status column to view the workflow status page. Figure 4 shows the workflow history, with the user input values.

Figure 4: You can tell that the code ran correctly because the values you entered via the form are displayed on the workflow status page.

Designing websites for accessibility in Expression Web – Part I

Have you ever come across a requirement where you have to create web content that is accessible to people with disabilities? If yes, then you may find this article useful, if not, then the article will help you understand why your websites need to be accessible and how to go about making them accessible. Lets us understand the importance of accessibility and see how to get that in our websites.
Accessibility is a vast topic and there are many aspects to be considered while creating an accessible website. In this article, I have tried to touch upon some important points to be considered while making you website accessible.
What is website accessibility?
There are many definitions of web accessibility. I find this definition simple to understand – ‘a practice to make websites usable to people of all abilities and disabilities’. People with disabilities may be visually impaired so may not be able to see your pages or hearing impaired will not be able to listen to your podcasts or those who are immobile may not be able to use their mouse or keyboard.
When you design a website, you need to consider making your website accessible to all the users especially those with disabilities, so that they can understand and interact with the web.
How to create accessible websites?
To create an accessible website, means to create web content that is accessible for all type of users. First you create the web content and then you test it for accessibility. For better understanding, I have divided this topic into two parts. In this article (Part I) I will show you how to make you content accessible and in the next part of the article, we will see how to check the content for accessibility.
To make you content accessible, follow these tips:
Setting accessibility properties for an image
Whenever you insert an image in your web page, Expression Web prompts you with an Accessibility Properties dialog box as shown below:
accessibility_properties
Alternate text or alt text is a textual alternative to the image which makes it accessible to the screen reader users. Another usage of alternate text is, if an image is being downloaded on the page or when image cannot be found and user hovers over the placeholder of the image, a small piece of text would explain what the image is about.
This Accessibility Properties dialog box is prompted every time you insert an image on your page, unless you uncheck the option ‘ Show this prompt when inserting images’ (see image above). On the other hand, to add an alternate text to an existing image, you can double click the image in Design view and in the Picture Properties dialog box (shown below) and in the Accessibility section, insert the Alternate text.
picture_properties
Alternatively, you can always set the alt attribute of the <img> tag to describe the image. And similarly, add an alt attribute to any animations on your page.
Setting accessibility properties for text hyperlinks and hotspots
Text Hyperlinks:
a. Select the text you want to convert into a hyperlink and right click on it.
b. From the menu choose Hyperlink…
c. In the Insert Hyperlink dialog box, click on ScreenTip…
insert_hyperlink
d. Enter the ScreenTip text which acts like the alternate text. This will add a title attribute to the <a> tag.
In addition to above, Hyperlink text should be short meaningful and should make sense when read out of context, either particularly that link or along with other links.
Image maps:
Just as you add screen tips to text hyperlinks to make them accessible, use them to make the hotspots accessible too. Follow these steps:
a. Insert the image onto your web page.
b. In the Pictures toolbar (if not visible, right click on any toolbar and choose Pictures from the menu) choose rectangular or circular hotspot.
c. Draw a hotspot on the image.
d. The Insert Hyperlink dialog box pops up as shown above.
e. Click on the ScreenTip… button to insert the screen tip. This will add a title attribute to the <area> tag.
Creating accessible Tables
Though tables can be used in page layouts, they are best used to organize data. CSS should be used for Page layouts and styles.
NOTE: Expression Web has a set of layout tables that you can use to create page layouts. Using them is quite simple.
Have you ever come across a requirement where you have to create web content that is accessible to people with disabilities? If yes, then you may find this article useful, if not, then the article will help you understand why your websites need to be accessible and how to go about making them accessible. Lets us understand the importance of accessibility and see how to get that in our websites.
Accessibility is a vast topic and there are many aspects to be considered while creating an accessible website. In this article, I have tried to touch upon some important points to be considered while making you website accessible.
Image maps:
Just as you add screen tips to text hyperlinks to make them accessible, use them to make the hotspots accessible too. Follow these steps:
a. Insert the image onto your web page.
b. In the Pictures toolbar (if not visible, right click on any toolbar and choose Pictures from the menu) choose rectangular or circular hotspot.
c. Draw a hotspot on the image.
d. The Insert Hyperlink dialog box pops up as shown above.
e. Click on the ScreenTip… button to insert the screen tip. This will add a title attribute to the <area> tag.
Creating accessible Tables
Though tables can be used in page layouts, they are best used to organize data. CSS should be used for Page layouts and styles.
NOTE: Expression Web has a set of layout tables that you can use to create page layouts. Using them is quite simple.
Table accessibility is all about adding appropriate headers to data tables. Header tags solve the purpose. Header tags <th> should be descriptive enough to describe what the table is about. Table headers are recognized by most of the browsers and rendered as bold and centered. These cause them to be visually effective to the users.
NOTE: TableHeaders should be used only for data tables and not for layouts.
To create table headers follow these steps:
a. After inserting a table, choose a cell and right click.
b. Choose Cell Properties to open the Cell Properties dialog box.
cell_properties
c. Check the box ‘Header cell’ and click OK.
d. This will convert the <td> tags to <th> tags.
e. Enter a table header.
Creating accessible Forms
Forms are extensively used by websites either as contact forms, search forms; online shopping websites have forms to buy products, or airline booking forms and such other. Accessibility in forms is an extensive area in itself as forms are not very simple to navigate for people with disabilities. I will cover Form accessibility in detail in one of my future articles, however over here I will give you some tips you may find useful in order to make your forms accessible.
1. Labels: Labels are used to assign a label to any form control. Use the ‘for’ attribute to specify which form control is it associated with and ‘id’ attribute to assign a unique id. Make sure labels are close to the form elements.
2. Text fields and areas: It is very difficult for blind users to interpret what to enter in a text field/area. So enter a label for the text fields.
3. Radio buttons and Checkboxes: They are similar to the text fields but the text is displayed on the right hand side. A common example for radio button would be gender. You could use a group box for such examples to group the options to be chosen in a section. Group box is explained further in this list.
4. Input buttons: Input buttons could be a normal button, submit button or reset button. The value attribute for these buttons is important so that when a user hits the tab key to get to this button, when it gets focus, it will be highlighted with a dotted border. In case of a user using a screen reader or a talking browser, it announces the text on the button.
5. Image buttons: Enter an alt attribute for the image button.
6. Group box: A group box enters a set of <fieldset> and <legend> tags. See the code below:
<fieldset name=”Group1″>
<legend>Group box</legend>
</fieldset>
Fieldsets: The fieldset tag helps to group form elements such as address line 1, address line 2 and address line 3. The fieldset tag draws a box around its containing elements and groups them.
Legend tag: is used along with the <fieldset> tag to add a title to the element group and place it within the frame.
7. Select menus or Drop down boxes: The <select> tag allows you to group choices, a drop down. Provide an appropriate label to it.
Creating accessible Frames
Frames are used to display two or more web pages in a single visual space. To be able to make these frames accessible, add a title to each frame. This will help the screen reader users to listen to the title of each of these frames, helping them to know what each frame displays.
The content in the <noframes> tag should be always available to the users. You can use the <noframes> tag to tell the users what is being displayed in the frames and also give them links to the individual pages displayed in frames, in case they want to visit.
Conclusion
Accessibility is a vast topic and there are many aspects to be considered while creating an accessible website. In this article, I have tried to touch upon some important points to be considered while making you website accessible. I hope the article was helpful to you. In the next article we will check the accessibility of the websites using the Accessibility Checker feature available in Expression Web.