jQuery ASP.NET: criando uma tela modal para edição de Grid

Veja neste artigo como utilizar ASP.NET com jQuery através de exemplos de utilização do jqGrid e também de uma tela modal para edição do Grid.

Hoje em dia escutamos muito falar sobre jQuery, mas afinal o que é e para que serve? Neste artigo veremos tudo isso e ainda aplicaremos exemplos práticos de como criar uma aplicação de cadastro utilizando jQuery.

O que é jQuery?

É uma biblioteca JavaScript cross-browser desenvolvida para simplificar os scripts client side que interagem com o HTML. Ela foi lançada em janeiro de 2006 no BarCamp de Nova York por John Resig. Usada por cerca de 55% dos 10 mil sites mais visitados do mundo, jQuery é a mais popular das bibliotecas JavaScript. Possui código aberto e licença dual, fazendo uso da Licença MIT ou da GNU General Public License versão 2.

Para que serve o jQuery?

A sintaxe do jQuery foi desenvolvida para tornar mais simples a navegação do documento HTML, a seleção de elementos DOM, criar animações, manipular eventos e desenvolver aplicações AJAX. A biblioteca também oferece a possibilidade de criação de plugins sobre ela. Fazendo uso de tais facilidades, os desenvolvedores podem criar camadas de abstração para interações de mais baixo nível, simplificando o desenvolvimento de aplicações web dinâmicas de grande complexidade.

Agora vamos ver na prática como ele funciona. Para isso, vamos implementar uma tela de cadastro em jQuery, para utilizando o JQuery 1.11.0, JQuery-ui-1.10.4 e o jqGrid 4.6.0.

Abra o Visual Studio e crie um novo projeto. Para isso, acesse o menu File -> New -> Project, conforme a Figura 1.

Figura 1. Iniciando o projeto

Na janela seguinte digite “empty” na caixa de pesquisa e selecione BlankSolution. Altere a propriedade Name para SLJQUERY ou para o nome que preferir, conforme mostra a Figura 2.

Figura 2. Criando a Solution

Se olharmos na Solution Explorer veremos que foi criada uma solução vazia, então agora clique com o botão direito do mouse e escolha Add... -> New Project. Crie um projeto do Tipo Web Application e altere a propriedade Name para JQuery_WEB, conforme demonstrado nas Figuras 3 e 4.

Figura 3. Adicionando um Novo Projeto
Figura 4. Adicionando um projeto Web Application

Para que seu projeto fique com uma aparência mais agradável, vamos criar algumas pastas para dividir os Arquivos de Script e os arquivos de banco de Dados, conforme as Figuras 5 e 6.

Figura 5. Adicionando uma nova Pasta
Figura 6. Pastas Criadas

Agora clique com o botão direito do mouse sobre a pasta Dados e selecione Add New item e na nova janela escolha a opção ADO.NET Entity Data model, conforme as Figuras 7 e 8.

Figura 7. Adicionando um novo Item
Figura 8. ADO.NET Data Entity

Como mostrado em imagens anteriores, nós criamos uma pasta Util. Como iremos trabalhar com JSON para transportamos os dados do banco para nosso jqGrid, armazenaremos nessa pasta algumas classes importantes para podermos trabalhar com o JSON. Assim, clique sobre a pasta Util e escolha a opção Add -> Class. Altere a propriedade name para GridResult, conforme as Figuras 9 e 10. A Listagem 1 tem o código da classe.

Figura 9. Adicionando uma Classe
Figura 10. Selecionando uma Nova Classe

Repita os passos das figuras acima e crie mais três classes com os respectivos nomes: GridRow, PagingArguments, JQGridExtensions. Para isso, implemente os códigos das Listagens 2 a 4.

using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace JQUERY_WEB.Util { /// <summary> /// Classe auxilia para definir a estrutura de retorno dos dados para o jqGrid /// </summary> public class GridResult { /// <summary> /// Página atual do grid /// </summary> public string page { get; set; } /// <summary> /// Total de páginas /// </summary> public int total { get; set; } /// <summary> /// Quantidade de linhas por página /// </summary> public string records { get; set; } /// <summary> /// Linhas de dados do grid /// </summary> public List<GridRow> rows { get; set; } } }
Listagem 1. Código GridResult
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace JQUERY_WEB.Util { /// <summary> /// Classe auxiliar para definir a estrutura da linha do jqGrid /// </summary> public class GridRow { /// <summary> /// Id da linha /// </summary> public string id { get; set; } /// <summary> /// Dados das células da linha /// </summary> public string[] cell { get; set; } } }
Listagem 2. Código GridRow
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace JQUERY_WEB.Util { /// <summary> /// Classe auxiliar para configurar a paginação do jqGrid /// </summary> public class PagingArguments { /// <summary> /// Número da página /// </summary> public int page { get; set; } /// <summary> /// Total de linhas por página /// </summary> public int limit { get; set; } /// <summary> /// Página inicial /// </summary> public int start { get; set; } /// <summary> /// Total de páginas /// </summary> public int totalPages { get; set; } } }
Listagem 3. Código PagingArguments
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Script.Serialization; using System.Runtime.Serialization; using System.Linq.Expressions; using System.IO; using System.Reflection; using System.Text; namespace JQUERY_WEB.Util { public static class JQGridExtensions { /// <summary> /// Configura o retorno para o grid /// </summary> /// <typeparam name="T"></typeparam> /// <param name="response"></param> /// <param name="page"></param> /// <param name="limit"></param> /// <param name="sortIndex"></param> /// <param name="sortOrder"></param> /// <param name="idColumn"></param> /// <param name="properties"></param> /// <returns></returns> public static GridResult ToJQGridResult<T>(this List<T> response, int page, int limit, string sortIndex, string sortOrder, string idColumn, string[] properties) { PagingArguments arguments = GetPagingVariables(response.Count(), page, limit); StringBuilder sortName = new StringBuilder(); sortName.Append(sortIndex); sortName.Append(" "); sortName.Append(sortOrder.ToUpper()); var sortedResult = response. AsQueryable<T>().SortBy<T>(sortName.ToString()) .Skip(arguments.start) .Take(arguments.limit); GridResult results = new GridResult(); results.page = arguments.page.ToString(); results.records = response.Count().ToString(); results.total = arguments.totalPages; results.rows = sortedResult.ToGridRowList(idColumn, properties); return results; } /// <summary> /// Método responsável pela paginação e ordenação do grid /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="propertyName"></param> /// <returns></returns> public static IQueryable<T> SortBy<T> (this IQueryable<T> source, string propertyName) { if (source == null) { throw new ArgumentNullException("source"); } int descIndex = propertyName.IndexOf(" DESC"); int ascIndex = propertyName.IndexOf(" ASC"); if (descIndex >= 0) { propertyName = propertyName.Substring(0, descIndex).Trim(); } if (ascIndex >= 0) { propertyName = propertyName.Substring(0, ascIndex).Trim(); } if (String.IsNullOrEmpty(propertyName)) { return source; } ParameterExpression parameter = Expression.Parameter(source.ElementType, String.Empty); MemberExpression property = Expression.Property(parameter, propertyName); LambdaExpression lambda = Expression.Lambda(property, parameter); string methodName = (descIndex < 0) ? "OrderBy" : "OrderByDescending"; Expression methodCallExpression = Expression.Call(typeof(Queryable), methodName, new Type[] { source.ElementType, property.Type }, source.Expression, Expression.Quote(lambda)); return source.Provider.CreateQuery<T>(methodCallExpression); } /// <summary> /// Retorna uma lista de GridRow's de acordo com as propriedades selecionadas. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="id"></param> /// <param name="properties"></param> /// <returns></returns> public static List<GridRow> ToGridRowList<T> (this IQueryable<T> source, string id, string[] properties) { List<GridRow> result = new List<GridRow>(); if (source == null) { throw new ArgumentNullException("source"); } if (string.IsNullOrEmpty(id)) { throw new ArgumentNullException("id"); } if (properties == null || properties.Length == 0) { throw new ArgumentNullException("properties"); } foreach (var item in source) { GridRow row = new GridRow(); Type type = item.GetType(); PropertyInfo info = type.GetProperty(id); row.id = info.GetValue(item, null).ToString(); row.cell = new string[properties.Length]; for (int i = 0; i < properties.Length; i++) { info = type.GetProperty(properties[i]); if (info.GetValue(item, null) != null) row.cell[i] = info.GetValue(item, null) .ToString(); } result.Add(row); } return result; } /// <summary> /// Retorna a paginação do grid /// </summary> /// <param name="countItems"></param> /// <param name="page"></param> /// <param name="limit"></param> /// <returns></returns> private static PagingArguments GetPagingVariables(int countItems, int page, int limit) { PagingArguments arguments = new PagingArguments(); //Set initial Values arguments.page = page; arguments.limit = limit; //Prepare paging variables float numberOfPages = (float)countItems / (float)limit; if (countItems > 0) { arguments.totalPages = (int)Math.Ceiling(numberOfPages); } //At least one page if (arguments.totalPages == 0) { arguments.totalPages = 1; } //Set actual page if (arguments.page > arguments.totalPages) { arguments.page = arguments.totalPages; } if (arguments.limit < 0) { arguments.limit = 0; } //Get paging variables arguments.start = arguments.limit * arguments.page - arguments.limit; if (arguments.start <= 0) { arguments.start = 0; } return arguments; } } }
Listagem 4. Código JQGridExtensions

Agora vamos criar um serviço que será responsável por acessar o banco de dados, esse serviço será consumido pelo jqGrid para alimentar o Grid com as informações desejadas. Clique sobre a pasta Services com o botão direito do mouse e selecione a opção Add -> New item. Escolha a Opção web service e altere a propriedade Name para WSjQuery, conforme exibido nas Figuras 11 e 12.

Figura 11. Adicionando um Web Service
Figura 12. Selecionando e nomeando Web Service

Agora devemos implementar o código para que o webservice acesse o banco de dados e traga as informações necessárias. Na Listagem 5 segue o código a ser implementado.

using System.Collections.Generic; using System.Web.Services; using System.Web.Script.Services; using System; using System.Linq; using JQUERY_WEB.Dados; using JQUERY_WEB.Util; namespace JQUERY_WEB.Services { /// <summary> /// Summary description for WSjQuery /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] [System.Web.Script.Services.ScriptService] public class WSjQuery : System.Web.Services.WebService { [WebMethod, ScriptMethod(ResponseFormat = ResponseFormat.Json)] public GridResult GetListAll(int page = 50, int rows = 25, string sidx = "FUNCIONARIO_ID", string sord = "desc", bool _search = true) { try { TutoriaisEntities t = new TutoriaisEntities(); List<FUNCIONARIOS> func = t.FUNCIONARIOS.ToList(); string[] properties = { "FUNCIONARIO_ID", "FUNCIONARIO_NOME", "FUNCIONARIO_SALARIO" }; GridResult jsonResults = ((List<FUNCIONARIOS>)func) .ToJQGridResult<FUNCIONARIOS>(page, (rows == -1 ? func.Count : rows), sidx, sord, "FUNCIONARIO_ID", properties); return jsonResults; } catch { //Implemente um tratamento de Erro. throw; } } } }
Listagem 5. Código do Web Service

Agora vamos implementar nossa interface. Para isso, acesse a solution explorer e clique com o botão direito do mouse sobre o projeto JQUERY_WEB e escolha Add -> webForm. Coloque o nome de Default.aspx, conforme a Figura 13 e 14.

Figura 13. Adicionando um Web Form
Figura 14. Nomeando Web Form

Os arquivos jQuery que você realizou download devem ser colocados na pasta Script e adicionados ao projeto, conforme mostra a Figura 15.

Figura 15. Arquivos jQuery

Agora vamos a implementação do arquivo asp.net para que ao ser executado o mesmo traga os dados em um grid do jqGrid. Nas Listagens 6 e 7 temos o código que deve ser implementado.

<head runat="server"> <title>Aplicação JQuery</title> <!--Arquivos CSS--> <link href="CSS/redmond/jQuery-ui.css" rel="stylesheet" /> <link href="Scripts/jQuery.jqGrid-4.6.0/css/ui.jqgrid.css" rel="stylesheet" /> <!--Scripts JQuery--> <script src="Scripts/jQuery-1.11.0.js"></script> <script src="Scripts/ui/jQuery-ui.js"></script> <script src="Scripts/jQuery.jqGrid-4.6.0/js/i18n/ grid.locale-pt-br.js"></script> <script src="Scripts/jQuery.jqGrid-4.6.0/js/ jQuery.jqGrid.min.js"></script> <!-- Implementação dos Scripts --> <script type="text/javascript"> $(document).ready(function () { /*MONTA O LINK DE EDIÇÃO DO GRID*/ function returnEditLink(cellValue, options, rowdata, action) { return "<span class='a' onclick=showDialog('" + cellValue + "');>" + cellValue + "</span>"; } /*MONTA O GRID*/ jQuery("#webgrid").jqGrid({ url: '../Services/WSjQuery.asmx/GetListAll', datatype: 'json', mtype: 'POST', ajaxGridOptions: { contentType: 'application/json; charset=utf-8' }, serializeGridData: function (data) { var propertyName, propertyValue, dataToSend = {}; for (propertyName in data) { if (data.hasOwnProperty(propertyName)) { propertyValue = data[propertyName]; if ($.isFunction(propertyValue)) { dataToSend[propertyName] = propertyValue(); } else { dataToSend[propertyName] = propertyValue } } } return JSON.stringify(dataToSend); }, postData: {}, jsonReader: { repeatitems: true, root: "d.rows", page: "d.page", total: "d.total", records: "d.records" }, colModel: [ { name: 'ID', index: 'FUNCIONARIO_ID', align: 'center', sorttype: 'string', width:35,formatter: returnEditLink }, { name: 'NOME', index: 'FUNCIONARIO_NOME', align: 'left' }, { name: 'SALÁRIO', index: 'FUNCIONARIO_SALARIO', align: 'right'} ], rowNum: 10, rowList: [10, 20, 30], pager: '#pager', sortname: 'FUNCIONARIO_ID', viewrecords: true, sortorder: "asc", width: 700, height: 500, left: 25, right: 100, margin: 45, caption: "Asp.Net JQuery JSON Example" }); }); /*FECHA O POPUP*/ function closeDialog() { $("#divId").dialog('close'); carregarGrid(); } /*EXIBE O POPUP*/ function showDialog(id) { id = null; $("#divId").html('<iframe id="modalIframeId" width="100%" height="100%" marginWidth="0" marginHeight="0" frameBorder="0" scrolling="auto" />').dialog({modal:true}); if (id == null) $("#modalIframeId").attr("src", "webModal.aspx"); else $("#modalIframeId").attr("src", "webModal.aspx?action=Edit&Id=" + id); return false; } //Função que pode ser chamado em um botão para atualizar o grid. function carregarGrid() { Vazio = 0; $("#webgrid").trigger("reloadGrid"); } </script> </head>
Listagem 6. Tag Head
<body> <form id="form1" runat="server"> <div > <table id="webgrid"> </table> <div id="pager"></div> </div> </form> </body>
Listagem 7. Tag Body

Dentro da Tag head deve ser adicionado primeiramente a referência dos arquivos jQuery a serem utilizados. Além disso, implementamos toda a chamada do código para criação do grid. Outro ponto importante é que a ordem de referência dos arquivos faz toda a diferença, pois um arquivo depende do outro, ou seja, a ordem que está na Listagem 6 deve ser mantida. Na tag table é obrigatório colocar um id é por esse que o método jQuery("#webgrid").jqGrid encontra onde ele deve montar o Grid.

Na Figura 16 veja como deverá ficar o seu grid.

Figura 16. Grid

Agora vamos implementar nossa tela modal para vincular ao grid quando clicar em um ID do grid e exibir os dados para Edição.

Acesse a solution explorer e insira um novo webform, conforme já mostrado nas Figuras 13 e 14 e dê o nome de webModal.aspx. Feito isso, no novo webform insira o código da Listagem 7.

<body> <form id="form1" runat="server"> <div> <table> <tr> <td></td> </td> <td> <asp:Label ID="lblId" Text="ID" runat="server"> </asp:Label> </td> <td> <asp:TextBox ID="txtId" runat="server"> </asp:TextBox> </td> </tr> <tr> <td></td> <td> <asp:Label ID="lblNome" Text="Nome" runat="server"> </asp:Label> </td> <td> <asp:TextBox ID="txtNome" runat="server"> </asp:TextBox> </td> </tr> <tr> <td></td> <td> <asp:Label ID="lblSalario" Text="Salário" runat="server"></asp:Label> </td> <td> <asp:TextBox ID="txtSalario" runat="server"> </asp:TextBox> </td> </tr> </table> </div> </form> </body>
Listagem 7. Tag Body

Agora acesse o arquivo webModal.aspx.cs e nesse arquivo implemente o código da Listagem 8. Esse código servirá apenas para preencher os campos com as informações do objeto selecionado na grid.

public partial class WebModal : System.Web.UI.Page { private int ID; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { ID = Convert.ToInt32(Request.QueryString.Get("id")); TutoriaisEntities entity = new TutoriaisEntities(); FUNCIONARIOS func = entity.FUNCIONARIOS.Where(f => f.FUNCAO_ID == ID).FirstOrDefault(); txtId.Text = func.FUNCIONARIO_ID.ToString(); txtNome.Text = func.FUNCIONARIO_NOME; txtSalario.Text = func.FUNCIONARIO_SALARIO.ToString(); } } }
Listagem 8. Código C# webModal

Agora vamos voltar ao Default.aspx e implementar os códigos da Listagem 9 e 10, que são as chamadas para o formulário ao clicar no grid.

<div id="pager"></div> <div id="divId"> </div> </form>
Listagem 9. Alterando a tag Form
/*FECHA O POPUP*/ function closeDialog() { $("#divId").dialog('close'); carregarGrid(); } /*EXIBE O POPUP*/ function showDialog(id) { id = null; $("#divId").html('<iframe id="modalIframeId" width="100%" height="100%" marginWidth="0" marginHeight="0" frameBorder="0" scrolling="auto" />') .dialog({modal:true}); if (id == null) $("#modalIframeId").attr("src", "webModal.aspx"); else $("#modalIframeId").attr("src", "webModal.aspx?action=Edit&Id=" + id); return false; }
Listagem 10. Alterando a Tag Script

O código acima deve ser incluído na Tag script, porém, fora da função $(document).ready. Após a inclusão desse código, ao clicar sobre o Id do funcionário na Grid abrirá uma tela modal, conforme a Figura 17.

Figura 17. Resultado Final

Ficamos por aqui, espero que tenham gostado e façam bom uso do jQuery e do Ajax que são dois excelentes auxílios no desenvolvimento para web.

Artigos relacionados