Asp.Net MVC 4 – Novidades para CSS e JavaScript    

Olá pessoal!

Hoje vou fazer um post bem rápido, apenas para comentar sobre a nova versão do Asp.Net MVC.

Para quem não sabe, a equipe do Asp.Net já está planejando a nova versão do Asp.Net MVC, e maiores detalhes podem ser encontrados aqui.

Para planejar as melhorias, eles definiram cinco guidelines, e no momento oportuno falarei de cada uma delas. Essas Guidelines vão de publicação e temas para Mobile à publicação na de sites na Nuvem.

O que achei interessante, e quis escrever esse post para comentar, é um item de publicação de site extremamente útil. Apesar de eles falarem que são apenas planos, e que qualquer coisa pode mudar, acho interessante comentar.

Eles estão planejando realizar um Build Integrado para CSS e JavaScript. Uma coisa que sempre senti falta no momento de compilar Web Applicattion.

A idéia seria, no momento da compilação do seu site, realizar a combinação de todos os seus arquivos CSS e JavaScript em apenas um (Um de cada tipo, naturalmente), e após realizar a combinação, fazer a minificação, ou seja, tirar todos os espaços desnecessários e comentários, além de alterações de nomes de algumas variáveis e funções, para diminuir consideravelmente o tamanho do arquivo.

Isso faria seu site carregar bem mais rápido, pois iria diminuir o número de requests por recursos do site (seria apenas um para cada tipo de recurso), além de diminuir o tempo de downloads, graças ao arquivo minificado (minified). Se você utilizar o Fiddler, por exemplo, para ver como é gasto o tempo de download de suas páginas, verá que esses arquivos realmente fazem diferença no load da página.

Como todos sabem, já existem ferramentas de minified disponíveis na internet, mas fazer todo esse trabalho manualmente para cada arquivo, e eventualmente combinar esses arquivos é uma tarefa bem enfadonha, e essa nova feature do Asp.Net MVC seria de muita ajuda.

Vamos torcer para que o time realmente implemente essa funcionalidade, porque acredito que é tipo de anuncio que dá brilhos nos olhos, mas é esquecido durante o processo de desenvolvimento. Afinal, as implicações de alterar e combinar arquivos automaticamente são inúmeras, e não são apenas boas implicações, afinal, alteraria nome de arquivo, o que teria que validar todas as referências em arquivos aspx ou cshtml, etc.

Vamos aguarda para ver o que o time do Asp.Net mostrará nos próximos meses. Todas as novidades serão mostradas nesse blog.

Abraços e até o próximo.

19. julho 2011 04:54 by Frederico B. Emídio | Comments (0) | Permalink

Como utilizar validação com Asp.Net MVC    

Olá pessoal!

Hoje vou falar de uma tarefa importante no desenvolvimento de sites: Validação.

Na construção de site nós nunca podemos confiar nas informações que o usuário informa, devemos saber que qualquer pessoa pode errar uma digitação ou esquecer de digitar uma informação qualquer, e por isso é importante saber utilizar Validação nos formulários que criamos.

No Asp.Net MVC existem várias formas de realizar validações, mas hoje vou falar de apenas três:

  • Adicionando informações à propriedade ModelState
  • Utilizando DataAnnotations
  • Utilizando DataAnnotations com JQuery

O processo de validação no Asp.Net MVC ficou muito fácil, eu diria que ficou muito mais fácil que no Asp.Net WebForm, vamos então começar pelo básico:

Validando suas Views com ModelState

A validação no Asp.Net MVC sempre é feita através do estado do modelo (ModelState) recebido na Action de um Controller, o que muda é como esse estado é alterado, pois pode feito manualmente, como faremos agora, ou automaticamente, através de ActionFilter customizado ou automático.

A forma básica é você adicionar manualmente informações de erro no modelo ao ModelState, invocando o método AddModelError(chave,mensagemDeErro).

Vamos aos exemplos! Para começar vou criar meu modelo, bem simples, como em todos os meus outros exemplos: Pessoa

   1:  public class Pessoa
   2:  {
   3:      public string Nome { get; set; }
   4:      public string Email { get; set; }
   5:      public string Telefone { get; set; }
   6:      public int Idade { get; set; }
   7:  }

Naturalmente, para criar uma pessoa no banco de dados, algumas informações devem ser obrigatórias e outras devem seguir algum formato específico, para todos os nossos exemplos usaremos as mesmas validações:

  • O nome é obrigatório.
  • O e-mail é obrigatório.
  • O telefone é obrigatório.
  • O e-mail deve seguir o formatado texto@texto.texto
  • A idade é deve ser maior que 18.
  • O telefone deve seguir o formato ####-####

Vou criar duas Actions de nome Edicao, uma para renderizar a View inicial e outra para persistir os dados, essa segunda terá a responsabilidade de fazer a validação do Modelo, e adicionar os erros ao ModelState. Caso não tenha erro, apenas redirecionará o usuário para a página inicial (persistir em uma base de dados não vem ao caso).

Abaixo segue o código das Actions:

   1:  public ActionResult Edicao()
   2:  {
   3:      return View();
   4:  }
   5:   
   6:  [AcceptVerbs(HttpVerbs.Post)]
   7:  public ActionResult Edicao(Pessoa pessoa)
   8:  {
   9:      //Valida os dados no lado do servidor.
  10:      if(string.IsNullOrEmpty(pessoa.Nome))
  11:      ModelState.AddModelError("Nome","Nome é obrigatório");
  12:      
  13:      if (string.IsNullOrEmpty(pessoa.Email))
  14:      ModelState.AddModelError("Email", "Email é obrigatório");
  15:      else{
  16:      if (!Regex.Match(pessoa.Email,@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$").Success)
  17:      ModelState.AddModelError("Email", "E-mail inválido.");
  18:      }
  19:   
  20:      if (pessoa.Idade <= 18)
  21:      ModelState.AddModelError("Idade", "Idade deve ser maior que 18.");
  22:   
  23:      if (string.IsNullOrEmpty(pessoa.Telefone))
  24:      ModelState.AddModelError("Telefone", "Telefone é obrigatório.");
  25:      else
  26:      {
  27:      if (!Regex.Match(pessoa.Telefone, @"^\d{4}[-]{1}\d{4}$").Success)
  28:          ModelState.AddModelError("Telefone", "Preencha um telefone no formato ####-####");
  29:   
  30:      }
  31:      //Verifica se algum erro acima falhou.
  32:      if (!ModelState.IsValid)
  33:      {
  34:      return View();
  35:      }
  36:      else
  37:      {
  38:      //Se estive certo só redireciono para a página inicial.
  39:      return Redirect("/");
  40:      }   
  41:  }

O código é bem intuitivo, caso tenha adicionado alguma mensagem de erro, a propriedade IsValid do ModelState retornará false, e o modelo estará inválido, assim eu retorno minha mesma View, que exibirá as mensagens de erros. Minha View fica da seguinte forma:

   1:  <%using(Html.BeginForm()){ %>
   2:  <p>
   3:  <%=Html.LabelFor(Model=>Model.Nome)%>
   4:  <%=Html.TextBoxFor(Model=>Model.Nome)%>
   5:  <%=Html.ValidationMessage("Nome")%>
   6:  </p>
   7:  <p>
   8:  <%=Html.LabelFor(Model=>Model.Email)%>
   9:  <%=Html.TextBoxFor(Model=>Model.Email)%>
  10:  <%=Html.ValidationMessage("Email")%>
  11:  </p>
  12:  <p>
  13:  <%=Html.LabelFor(Model=>Model.Telefone)%>
  14:  <%=Html.TextBoxFor(Model=>Model.Telefone)%>
  15:  <%=Html.ValidationMessage("Telefone")%>
  16:  </p>
  17:  <p>
  18:  <%=Html.LabelFor(Model=>Model.Idade)%>
  19:  <%=Html.TextBoxFor(Model=>Model.Idade)%>
  20:  <%=Html.ValidationMessage("Idade")%>
  21:  </p>
  22:  <p>
  23:  <input type="submit" value="Salvar"/>
  24:  </p>
  25:  <%} %>

Veja que a única novidade da minha View a utilização do HTMLHelper ValidationMessage, passando o nome da chave que eu valido no servidor. Ao executar minha tela, caso passe informações inválidas, terei o seguinte resultado:

image

Ou assim:

image

E a sua validação está pronta para ser usada! Eu poderia utilizar um ValidationSummary, apenas utilizando o helper para isso, da seguinte forma: <%=Html.ValidationSummary()%>.

Vamos à nossa segunda forma de validar nosso modelo.

Validando suas Views com DataAnnotarions

DataAnnotations é uma forma de você adicionar validações ao seu modelo através de atributos, incorporada ao .Net 4. O interessante dessa estratégia é que não está ligada ao Asp.Net MVC, portanto, você pode utilizá-la tanto em Asp.Net, como em qualquer outra tecnologia .Net, como WCF. Isso é muito importante, pois você não precisa repetir validação em diversas partes do código, técnica conhecida como DRY (Don’t Repeat Yourself).

Como a validação é centralizada no modelo, nosso modelo sofrerá uma pequena alteração, assim como nossa Action, pois tiraremos a validação da Action e passaremos para o modelo. Nosso modelo ficará assim:

   1:  public class Pessoa
   2:  {
   3:      [Required(ErrorMessage = "O Nome é obrigatório.")]
   4:      public string Nome { get; set; }
   5:   
   6:      [Required(ErrorMessage = "O E-mail é obrigatório.")]
   7:      [RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", ErrorMessage = "E-mail inválido.")]
   8:      public string Email { get; set; }
   9:   
  10:      [Required(ErrorMessage = "O Telefone é obrigatório.")]
  11:      [RegularExpression(@"^\d{4}[-]{1}\d{4}$", ErrorMessage = "Telefone inválido. Informe ####-####.")]
  12:      public string Telefone { get; set; }
  13:   
  14:      [Range(18, Int16.MaxValue, ErrorMessage = "A idade deve ser maior que 18 anos.")]
  15:      public int Idade { get; set; }
  16:  }

Veja que existem vários tipos de atributos de Validação, e para todos eu posso informar uma mensagem de erro personalizada, através da propriedade ErrorMessage, além de cada um ter propriedades específicas de acordo com o tipo.

Como toda a lógica de validação passou para o modelo, nossa Action ficará bem mais simples:

   1:  [AcceptVerbs(HttpVerbs.Post)]
   2:  public ActionResult Edicao(Pessoa pessoa)
   3:  {
   4:      //O modelo já chega validado
   5:      if (!ModelState.IsValid)
   6:      {
   7:      return View();
   8:      }
   9:      else
  10:      {
  11:      //Se estive certo só redireciono para a página inicial.
  12:      return Redirect("/");
  13:      }
  14:  }

Veja como ficou simples a Action agora, e o resultado nas Views é o mesmo, não mudei nada no meu HTML, apenas adicionei um Summary, para ver que o resultado é o mesmo:

image

E mais uma forma de validação já está funcionando e pronta para publicar!

Mas espera aí! Existe um problema nessas duas formas de validação: Ela são realizadas no servidor. Ou seja, o usuário precisa ser submetido ao servidor para realizar a validação, o que pode prejudicar muito a experiência do usuário, e para isso termos a terceira forma de validação de hoje:

Utilizando DataAnnotations com JQuery para validação no Cliente

O mais interessante da utilização do JQuery com DataAnnotation é o impacto no código do servidor: Nada! Isso mesmo, não tem impacto nenhum no servidor para você adicionar validação no Asp.Net MVC no cliente. Vou fazer a seguinte alteração no HTML:

 

   1:  <% Html.EnableClientValidation();%>
   2:  <%using (Html.BeginForm())
   3:  { %>
   4:  <p>
   5:  <%=Html.LabelFor(Model=>Model.Nome)%>
   6:  <%=Html.TextBoxFor(Model=>Model.Nome)%>
   7:  <%=Html.ValidationMessageFor(Model => Model.Nome)%>
   8:  </p>
   9:  <p>
  10:  <%=Html.LabelFor(Model=>Model.Email)%>
  11:  <%=Html.TextBoxFor(Model=>Model.Email)%>
  12:  <%=Html.ValidationMessageFor(Model => Model.Email)%>
  13:  </p>
  14:  <p>
  15:  <%=Html.LabelFor(Model=>Model.Telefone)%>
  16:  <%=Html.TextBoxFor(Model=>Model.Telefone)%>
  17:  <%=Html.ValidationMessageFor(Model => Model.Telefone)%>
  18:  </p>
  19:  <p>
  20:  <%=Html.LabelFor(Model=>Model.Idade)%>
  21:  <%=Html.TextBoxFor(Model=>Model.Idade)%>
  22:  <%=Html.ValidationMessageFor(Model => Model.Idade)%>
  23:  </p>
  24:  <p>
  25:  <input type="submit" value="Salvar" />
  26:  </p>
  27:  <%} %>

As alterações na view foram pequenas, adicionei o Helper EnableClientValidation e mudei ValidationMessage por ValidationMessageFor, fora isso, foi necessário adicionar referência a alguns arquivos JS (JavaScript), você pode adicionar tanto no seu arquivo de Layout  (Master) ou na própria View. Os arquivos são os seguintes:

 

   1:  <script src="<%=Url.Content("~/Scripts/jquery-1.4.1.min.js")%>" type="text/javascript"></script>
   2:  <script src="<%=Url.Content("~/Scripts/jquery.validate.js")%>" type="text/javascript"></script>
   3:  <script src="<%=Url.Content("~/Scripts/MicrosoftMvcJQueryValidation.js")%>" type="text/javascript"></script>
 

Os arquivos que adicionei são os arquivo do próprio JQuery (a versão desatualizada que vem com o Visual Studio 2010, que você pode mudar para a atual), o plug-in Validate do Jquery e um arquivo fornecido pelo time do Asp.Net para fazer o meio campo entre a validação do Asp.Net com o JQuery de forma totalmente transparente. Esse arquivo pode ser baixado com o Asp.Net MVC Futures, clicando aqui.

O Resultado é o mesmo:

image

E assim sua validação já estará funcionando no cliente. O mais legal dessa abordagem é que você realizará a validação tanto no Cliente como no Servidor, sem repetir uma linha de código (DRY).

No servidor que eu digo não é como no WebForm, onde a validação de um Validator Control também funciona tanto no servidor como no cliente, porque naquele caso, é apenas no servidor Asp.Net, visto que a validação está na página. Nesse caso, a validação está no Modelo, logo, o mesmo código pode ser utilizado em uma classe de negócio, WCF, WWF, etc; sem replicação de código.

Existe uma validação nativa no lado do Cliente no MVC, mas preferi mostrar com o Jquery, porque é possível integrar outros plug-ins com a validação, que podem gerar efeitos bem interessantes à sua página.

Bom, acredito que seja o suficiente para você adicionar validação ao sua página, de forma bem clara sem ter que se esforçar muito.

Abaixo você pode baixar uma solução contendo três projetos, um com cada tipo de validação, para você ver que não existe grandes diferenças entra elas.

Abraços e até o próximo pessoal.

ValidatorsMVC.zip (1,00 mb)

27. fevereiro 2011 06:06 by Frederico B. Emídio | Comments (0) | Permalink

Reaproveitando View em Asp.Net MVC    

Olá pessoal!

Hoje vou fazer um post bem pequeno, mas que é uma resposta a uma pergunta deve surgir na cabeça de todo mundo que começa em MVC. Já tive essa dúvida no passado, já ouvi essa pergunta em WebCasts e me fizeram ela semana passada: Para cada Action eu devo ter uma View, mesmo que o formulário seja igual?

Mesmo no meu post de CRUD eu fiz assim, criei uma View para a Action Create e outra para a Action Edit, mas a idéia era realmente possibilitar a evolução do projeto, como fiz aqui e aqui, e agora nesse atual vou continuar aprimorando aquele projeto.

Nesse post vou mostrar que isso não é necessário, e em uma aplicação de verdade deve ser evitado, afinal programar repetidas vezes as mesmas regras de validação sempre é um risco para a manutenção.

Vamos ao código!

Primeiramente, excluí as Action Create, e sua respectiva View, para ser utilizada apenas a Action e View Edit. Vou inicialmente mostrar como ficou o código da View. Como agora não necessariamente ao carregar a View eu terei os dados para preencher os campos, devo fazer um preenchimento condicional, da seguinte forma:

<form name="formCadastro" action="Edit" method="post">
<input type="hidden" id="hdfCodigo" name="id" value="<%=ViewData.Model.Codigo??"" %>" />
<h2>Alterar Contato</h2>
<p>
<span>Nome</span><input type="text" value="<%=ViewData.Model.Nome??"" %>" name="txtNome"
    id="txtNome" /></p>
<p>
<span>E-mail</span><input type="text" value="<%=ViewData.Model.Email??""%>" name="txtEmail"
    id="txtEmail" /></p>
<p>
<span>Telefone</span><input type="text" id="txtTelefone" value="<%=ViewData.Model.Telefone??"" %>"
    name="txtTelefone" /></p>
<p>
<input type="submit" value="Salvar" /></p>
</form>

Perceba que estou utilizando o operador ??, que verificar se o valor à esquerda é nulo e se for, utiliza o da direita. Na View, toda a alteração necessária é essa.

Nas minhas Actions fiz as seguintes mudanças:

   1:  public ActionResult Edit(int? id)
   2:  {
   3:      if (!id.HasValue) return View(new Pessoa());
   4:   
   5:      using (var bd = new bdEntities())
   6:      {
   7:      var pessoa = (from p in bd.Pessoa
   8:                where p.Codigo == id
   9:                select p).First();
  10:   
  11:      return View(pessoa);
  12:      }
  13:  }
  14:   
  15:  [HttpPost]
  16:  public ActionResult Edit(int id, FormCollection collection)
  17:  {
  18:      try
  19:      {
  20:      using (var bd = new bdEntities())
  21:      {
  22:          if (id ==0)
  23:          {
  24:          var pessoa = new Pessoa();
  25:          pessoa.Email = collection["txtEmail"];
  26:          pessoa.Nome = collection["txtNome"];
  27:          pessoa.Telefone = collection["txtTelefone"];
  28:          bd.AddToPessoa(pessoa);
  29:          bd.SaveChanges();
  30:          }
  31:          else
  32:          {
  33:          var pessoa = (from p in bd.Pessoa
  34:                    where p.Codigo == id
  35:                    select p).First();
  36:   
  37:          pessoa.Email = collection["txtEmail"];
  38:          pessoa.Nome = collection["txtNome"];
  39:          pessoa.Telefone = collection["txtTelefone"];
  40:          bd.SaveChanges();
  41:          }
  42:      }
  43:   
  44:      return RedirectToAction("Index");
  45:      }
  46:      catch
  47:      {
  48:      return View();
  49:      }
  50:  }

Na linha 1, mudei o tipo do parâmetro para Nullable<Int>, isso porque quando eu for criar um novo registro, não vou ter o ID ainda. Na linha 3 eu verifico se o ID está preenchido, se não estiver, considero que é um novo registro e retorna a View com a instância de Pessoa sem as informações preenchidas. Caso tenha valor preenchido, continuo o método como era antes, para ter o comportamento de alteração.

No segundo método, verifico se o ID é um ID novo (valor 0) ou se é uma alteração, e realizo o procedimento adequado, com isso eu utilizo a mesma view tanto para as ações de Criar como Editar, e dessa forma, não replico código de interface (View).

Em alguns casos, em vez de eu criar a lógica na Action dessa forma, eu poderia criar duas Actions com nomes distintos (Create e Edit) e na Create, utilizar o método RedirectToAction, passando como parâmetro o nome do método Edit, são apenas abordagens diferentes, mas que teriam o mesmo resultado. Naturalmente, o método RedirectToAction pode ser utilizados em outros contextos, como eu estou fazendo na linha 44, para redirecionar o navegador para a Action Index, e exibir a listagem atualizada.

Bom, como eu disse o post seria curto, e era isso que tinha para falar.

Clique no link abaixo para baixar o projeto atualizado, inclusive corrigindo um bug do arquivo anterior Smiley de boca aberta.

MvcCrud.zip (641,09 kb)

Até o próximo!



  
     
  
25. janeiro 2011 11:23 by Frederico B. Emídio | Comments (0) | Permalink

Tarefas Básicas com Asp.Net MVC Pt. III–Grid com plugin JQuery JQGrid    

 

Olá Pessoal!

Depois de um longo tempo sem escrever, devido a um projeto atrasado, vou finalizar a série sobre tarefas básicas com Asp.Net MVC.

Você viu neste e neste post como criar um cadastro em MVC. Porém, eu criei um grid muito simples, apenas usando as simples tags TABLE do HTML. Quando um iniciante em MVC vê isso, ele já se pergunta: “Mas e todas aquelas facilidades do GridView? Vou ter que criar na mão?”. A resposta é não. Existem muitas grids por ai que funcionam muito bem com Asp.Net MVC, e hoje vou mostrar como utilizar a que eu mais gosto, inclusive em WebForms (exatamente, eu não uso GridView a muito tempo).

A Grid que vou apresentar é um plugin Jquery muito bem feito, chamado JQGrid. Esse plugin tem constantes atualizações, com melhorias e correções, além de ter muitas referências na Web. O próprio site do plugin tem uma parte Wiki com todo o conteúdo necessário para você fazer tudo o que for necessário em um sistema, desde a simples grid com paginação até a SubGrid, Agrupamento, Edição inline, edição em popup,  entre muitas outras coisa, tudo em poucas linhas de códigos. As funcionalidades são separadas em módulos, e você pode baixá-los separadamente. Dê uma olhada aqui que você verá quantas possibilidades existem nesta grid. Além disso, o layout da grid é baseado nos temas do JQuery UI, ou seja, criar temas para grid é muito fácil a partir do site do JQuery UI

O objetivo deste post não é explicar amplamente o plugin, apenas mostrar como pode ser feita a integração com uma Action, a partir daí, muito mais pode se feito.

Então vamos lá!

Instalando o Plugin JQGrid

Para baixar a última versão, você pode acessar aqui. Nessa tela, você poderá selecionar quais módulos da grid deseja baixar, no meu caso eu vou selecionar todos, mas você pode ver com mais atenção quais são realmente necessários para um projeto real. Quanto mais módulos, maior o arquivo, e na internet isso ainda faz uma diferença.

Quando baixamos o Plugin, temos uma pasta src, que você pode estudar para ver como a Grid funciona, mas para adicionar em nosso site, precisamos apenas adicionar o arquivo jquery.jqGrid.min.js, que conterá tudo necessário para a Grid rodar. Além desse arquivo, existe também uma pasta chamada i18n, onde você encontrará arquivos de linguagens, adicione a que você achar melhor, eu vou adicionar apenas o arquivo de Português do Brasil.

Adicionado os arquivos de Scripts, você deve também adicionar os arquivos de layout (CSS). Dois arquivos devem ser adicionados, o CSS da Jquery UI, que pode ser baixado aqui, e o arquivo que complementa o CSS do UI, que vem com o download do JQGrid, chamado ui.jqgrid.css

Meu projeto (o mesmo do artigo anterior) ficará assim:

image

image

Após adicionarmos os arquivos ao nosso projeto, devemos adicionar a referência no HTML, tanto para os JS’s como para os CSS’s. Vou fazer isso na View Index, onde tenho a tabela HTML:

<link rel="Stylesheet" href="../../Content/jquery-ui-1.7.2.custom.css" />
<link rel="Stylesheet" href="../../Content/ui.jqgrid.css" />
<script type="text/javascript" src="../../Scripts/jquery-1.4.1.js"></script>
<script type="text/javascript" src="../../Scripts/i18n/grid.locale-pt-br.js"></script>

Como todo plugin Jquery, a configuração da Grid é feito pelo seu construtor, em cima de alguma tag do HTML selecionado pelo seletor do JQuery. Para criar a Grid, utilizei o seguinte código, em cima da table com id=table:

<script type="text/javascript">
$().ready(function () {
    $("#table").jqGrid({
    multiselect: false,
    datatype: "json",
    url: "Listar",
    colNames: ['Nome', 'Email', 'Telefone'],
    colModel: [
    { name: 'Nome', index: 'Nome', width: 100 },
    { name: 'Email', index: 'Email', width: 300 },
    { name: 'Telefone', index: 'Telefone', width: 80 }
     ],
    height: 220,
    caption: "Resultado",
    pager: "#pager",
    jsonReader: { repeatitems: false, id: "Codigo" },
    rowNum: 10,
    sortname: 'NomeEmpresa',
    sortorder: "asc",
    viewrecords: true
    });
 
});
        
</script>
<table id="table"></table>
<div id="pager"></div>

Vou explicar resumidamente alguns parâmetros, mas se você quiser uma explicação mais detalhada de cada opção, acesse a página do plugin, clicando aqui ou na wiki do site, vamos la:

Parâmetro Descrição
datatype Indica que tipo de dado a grid deve tratar, pode ser JSON, XML, local, entre outros.
url Método no servidor que realizará a pesquisa, no caso a Action, poderia ser uma WebService ou um PageMethods do WebForms. Se o tipo do dado for local, você não precisa desse parâmetro.
colNames Nome (Header) de cada Coluna, se você tiver uma coluna sem nome, só com um checkbox, por exemplo, você deve informar espaços em brancos, a quantidade de itens em ColNames deve ser igual a quantidade de colunas no ColModel
colModel Aqui é onde você define como será cada coluna, as opções são inúmeras, então visite o site para ver mais.
pager Indica em qual controle o plugin criará os controles de paginação. Geralmente é uma div, como no exemplo. Existem muitas opções de pager também, visite o site!
jsonReader Informa a estrutura que os dados devem vir do servidor, e qual é o ID dos dados. A variação também é ampla, estou usando o default.

 

A grid acima ficaria como a imagem abaixo.

image

Usando apenas as configurações padrões, minha grid já é totalmente funcional, com paginação e ordenação por coluna. Como disse, cada opção abre uma grande gama de opções, o site do plugin é bem completo e minha intenção não é replicar o site aqui, apenas apresentar a Grid.

Essas configurações delegam a responsabilidade de paginação e ordenação no servidor, mudando um pouco você poderia ter a ordenação e paginação controlada pela própria Grid, porém, é lógico que é muito mais rápido (no sentido de desempenho em tempo de execução) fazer isso tudo no servidor, além de poupar muito a banda de internet transferindo apenas os dados que serão exibidos para o cliente.

Minha action Listar ficou assim (Implementei apenas a paginação para demonstração, o código naturalmente não é um código de produção, afinal, a idéia é apresentar a grid):

[Obs: Código alterado para correção da lógica]

   1:  {
   2:      using (var bd = new bdEntities())
   3:      {
   4:      var query = from pessoas in bd.Pessoa 
   5:              select pessoas;
   6:      var ini = (page - 1) * 10;
   7:      var fim = query.Count()> 10? 10: query.Count();
   8:      if (ini > 0)
   9:      {
  10:          fim = 10;
  11:          fim = fim - 10 >= 0 ? query.Count() % 10 : fim;
  12:      }
  13:   
  14:      var totalPags = query.Count() / 10;
  15:      if (query.Count() % 10 > 0)
  16:      {
  17:          totalPags++;
  18:      }
  19:      var jsonData = new
  20:      {
  21:          total = totalPags, // número de páginas retornadas no reader
  22:          page = page,
  23:          records = query.Count(), // número total de registros na base.
  24:          rows = query.ToList().GetRange(ini,fim)
  25:      };
  26:      return Json(jsonData, JsonRequestBehavior.AllowGet);
  27:      }
  28:  }

Algumas considerações ao código:

Minha Action retorna um JsonResult, afinal é um objeto Json que minha grid espera. O método Json fica responsável por converter meu objeto jsonData em Json. Apesar de eu estar criando a variável jsonData como um objeto dinâmico, eu poderia definir essa classe como uma classe concreta, e utilizar os parâmetros por toda a aplicação, é assim que costumo fazer.

As propriedades do jsonData seguem um padrão nomes de acordo com o definido no jsonReader (parâmetro da Grid), se você mudar alguma coisa no padrão do jsonReader terá que mudar também nas propriedades de retorno, mais uma vez: todas essas inúmeras possibilidades estão no site do plugin.

Os parâmetros da Action também devem seguir essa assinatura, para que o Asp.Net consiga traduzir os parâmetros vindo do JavaScript diretamente para os parâmetros. Você pode mudar  essas regras com um pouco mais de programação, que, alias, eu acho uma boa idéia se você estiver pensando em adotar a Grid como padrão de lista para seus sistemas, quanto menos parâmetros, mais rápido para desenvolver!

A lógica de paginação não faz parte da solução, é claro.Alegre

Conclusão

A idéia desse post foi apresentar o plugin JQGrid, e mostrar que o mundo sem server controls não é tão difícil assim, eu já uso essa grid a muito tempo em WebForms, porque é uma solução muito mais poderosa e versátil que o GridView. Acredite em mim, cada nova possibilidade que você descobre nesse plugin, você fica mais fascinado e confiante.

O exemplo que mostrei, não mostrou nenhuma possibilidade do plugin, mas se você quiser ter uma noção da capacidade dele, clique aqui e veja com seus próprios olhos.

Para baixar o código do exemplo, clique link abaixo

Baixar Arquivo

20. janeiro 2011 23:55 by Frederico B. Emídio | Comments (3) | Permalink

Tarefas Básicas com Asp.Net. Parte II – HTML Helpers.    

Olá pessoal, nessa semana vo fazer um post bem simples, No post anterior, criei um cadastro básico. Nele, quis deixar claro que queria fazer tudo na mão, criando todo o HTML, apenas para tentar deixar mais claro como funciona a integração entre View e Controller.

Neste post, vou mostra como podemos diminuir a tarefa, muitas vezes enfadonha, de ficar digitando HTML constantemente, através da utilização de HTML Helpers

O que é um HTML Helper

HTML Helper são métodos estáticos que retornam simples strings. Lembre que no Asp.Net MVC não tem server controls como no WebForm, portanto, não espere que um HTML Helper te retorne um “controle” HTML onde você pode definir propriedades após a criação do mesmo via C#. Como disse, ele só retorna strings, em geral que represente uma tag HTML. Você pode criar também qualquer tipo de HTML Helper, mas isso é assunto para outro post, neste vamos apenas falar da utilização.

Por padrão, o Asp.Net MVC já vêm com uma série de Helper pré definidos, alguns deles estão na listagem abaixo:

  • Html.BeginForm()
  • Html.EndForm()
  • Html.TextBox()
  • Html.Hidden()
  • Html.ActionLink()
  • Html.CheckBox()
  • Html.DropDownList()
  • Html.ListBox()
  • Html.Password()
  • Html.RadioButton()
  • Html.TextArea()

A lista acima não tem todos os Helper, mas os mais comuns para criar um formulário de cadastro, por exemplo.

A utilização dos Helpers te abstrai das regras da criação dos formulários. Por exemplo, no exemplo do post anterior, o formulário de criação era o seguinte:

   <form name="formCadastro" action="Create" method="post">
    <h2>
        Criar novo Contato</h2>
    <p>
        <span>Nome</span><input type="text" name = "txtNome" id="txtNome" /></p>
    <p>
        <span>E-mail</span><input type="text" name = "txtEmail"  id="txtEmail" /></p>
    <p>
        <span>Telefone</span><input type="text" id="txtTelefone" name = "txtTelefone"  /></p>
    <p>
        <input type="submit" value="Salvar" /></p>
    </form>

Utilizando os Helpers, ele ficaria da seguintes forma:

    
<%using(Html.BeginForm()){ %>
 <h2>
        Criar novo Contato</h2>
    <p<
        <span>Nome</span><%:Html.TextBox("txtNome")%></p>
    <p>
        <span>E-mail</span><%:Html.TextBox("txtEmail")%></p>
    <p>
        <span>Telefone</span><%:Html.TextBox("txtTelefone")%></p>
    <p>
        <input type="submit" value="Salvar" /></p>
    <%} %>

Perceba que nitidamente tem menos HTML criado, e menos conhecimento de infra estrutura Web é necessário, pois eu não precisei definir o tipo do método do formulário, não precisei definir a Action, o Helper Html.BeginForm presumiu todo o necessário para criar o formulário.

É interessante notar também que em vezes de invocar o BeginForm e o EndForm, utilizei uma diretiva using como muitas vezes é utilizado no C# para definir o início e fim de uma instância de um objeto. Dessa forma, o HTML Helper sabe onde deve colocar o a tag final do formulário, sem a necessidade de utilizar o helper EndForm.

E para criar os textboxes, informei apenas um parâmetro e ele já presumiu o id e o name do controle. Se você fizer essas alterações no exemplo do post anterior, verá que a página funcionará do mesmo jeito, sem necessitar de nenhuma alteração no Controller.

Perceba também que, com exceção do BeginForm, os demais helper precisam ser inseridos dentro de uma tag que imprime texto do Asp.Net. No caso, utilizei as tags Asp.Net <%:Html.TextBox("txtNome") %>, poderia também <%= Html.TextBox("txtNome")%>, ou até mesmo um <%Response.Write(Html.TextBox("txtNome"));%>, lembre-se sempre, eu preciso colocar as tags de print ou utilizar o Response.Write, porque o helper retorna apenas uma string.

Outro exemplo de utilização muito útil de um Html Helper, seria para criar links, sem a necessidade de ter que informar o nome do Controller e da Action, como de costume. Por exemplo, o link abaixo:

<a href="Cadastro/Create">Novo</a>

Poderia ser criado utilizando um Helper da seguinte forma:

<%:Html.ActionLink("Nome","Create") %>

Perceba que não preciso assim conhecer quais são os atributos necessários de um link, apenas definir um texto para o link e saber qual Action invocar no meu Controller atual.

Bom, você viu como pode ser utilizado os Helpers HTML do MVC, é bom conhecer toda a lista existente de Helpers, para podermos maximizar o desempenho no desenvolvimento de sites com MVC, e, é claro, é importante saber que é possível, e simples, criar novos Helpers, para criar estruturas mais complexas, ou mesmo criar conjuntos de Tags que você utiliza sempre, como uma tela de acesso, ou um controle JQuery de tabs. Isso falaremos em um próximo post.

É isso, como comentei, o post hoje seria bem simples.

Até o próximo!

12. dezembro 2010 20:03 by Frederico B. Emídio | Comments (1) | Permalink

Sobre mim

Minha Imagem

Meu nome é Frederico Batista Emídio, trabalho com desenvolvimento de sistemas profissionalmente a oito anos, porém, já faço sites pessoais a pelo menos dez anos.

Para saber mais clique aqui.

Páginas

Calendário

<<  novembro 2017  >>
seteququsedo
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

Visualizar posts em um Calendário
Sigua @fredemidio

MCP Asp.NET