Turbinando o ASP.NET GridView: Mudando a cor no onMouseOver e selecionando registros com clique na Linha
Olá pessoal! Dando seqüência a nossa "turbinagem" das interfaces em ASP.NET, vamos tratar dos nossos grids? Um grid é uma das portas de entrada para editar os registros. Pesquisamos por um filtro e os resultados são exibidos nele. Para editar, clicamos em um botão que ou leva para uma página ou abre uma janela modal com os detalhes.
Neste artigo iremos "capar" do nosso grid o botão de Editar. Para o usuário editar um registro, clicaremos em qualquer ponto da linha, além de acrescentarmos efeitos durante a escolha do registro e a seleção.
Não se esqueça de baixar o exemplo da nossa página de suporte no final do post, é lá que o exemplo será baseado ok?
Primeiramente, vamos definir alguns estilos CSS que iremos utilizar na página. Eles podem ser colocados em um arquivo a parte ou na própria página:
1: .header {
2: font-family:verdana; font-weight:bold;
3: font-size:8pt; background-color:red; color:white;
4: }
5: .normal {
6: font-family:verdana; font-size:8pt;
7: background-color:silver; color:black;
8: }
9: .hover {
10: font-family:verdana; font-size:8pt;
11: background-color:green; color:white;
12: }
13: .selected {
14: font-family:verdana; font-size:8pt;
15: background-color:blue; color:white;
16: }
Os nomes dos estilos coincidem onde eles serão aplicados, para facilitar a nossa vida :-)
Agora, consideremos o nosso gridview com a formatação básica já aplicada:
1: <asp:GridView runat="server" ID="gvDados" AutoGenerateColumns="false" Width="100%"
2: OnRowDataBound="gvDados_RowDataBound">
3: <HeaderStyle CssClass="header" />
4: <RowStyle CssClass="normal" />
5: <Columns>
6: <asp:BoundField HeaderText="Código" DataField="Codigo" />
7: <asp:BoundField HeaderText="Nome" DataField="Nome" />
8: <asp:BoundField HeaderText="Data de Cadastro" DataField="DataCadastro" DataFormatString="{0:dd/MM/yyyy}" />
9: <asp:TemplateField ItemStyle-HorizontalAlign="Center">
10: <ItemTemplate>
11: <asp:Button runat="server" ID="btnEditar" Text="Editar" OnClick="btnEditar_Click" />
12: <asp:Button runat="server" ID="btnExcluir" Text="Excluir" OnClick="btnExcluir_Click"
13: OnClientClick="return confirm('Senta o dedo? hehe');" />
14: </ItemTemplate>
15: </asp:TemplateField>
16: </Columns>
17: </asp:GridView>
No header do grid colocamos a classe CSS "header" e nas linhas a classe "Normal". O que queremos fazer neste momento é que ao repousar o mouse em cada linha ela mude de cor e quando retirarmos o mouse ela volta ao normal. Como fazer isso? Vamos usar JavaScript e alterar a classe CSS da linha!
Sim, adicionaremos aos eventos "onMouseOver" e "onMouseOut" um código JavaScript que trocará a classe CSS da linha para "hover" e "normal", respectivamente. Para isso, vá até o editor de código e codifique o evento RowDataBound do GridView da seguinte forma:
1: protected void gvDados_RowDataBound(object sender, GridViewRowEventArgs e)
2: {
3: if (e.Row.RowIndex > -1)
4: {
5: //Guardamos em cada botão, na propriedade CommandArgument, o índice da linha do gridview
6: (e.Row.FindControl("btnEditar") as Button).CommandArgument = e.Row.RowIndex.ToString();
7: (e.Row.FindControl("btnExcluir") as Button).CommandArgument = e.Row.RowIndex.ToString();
8:
9: //Aqui vamos fazer cada linha do gridview mudar de cor ao repousar/afastar o mouse
10: e.Row.Attributes.Add("onMouseOver", "this.className = 'hover';");
11: e.Row.Attributes.Add("onMouseOut", "this.className = 'normal';");
12: }
13: }
Dentro do bloco if, as duas primeiras linhas servem para guardar o índice de cada linha do grid no atributo CommandArgument dos botões Editar e Excluir de cada linha. Utilizaremo-os na segunda parte deste tutorial, que tratará da seleção do registro com o clique.
No bloco que interessa no momento, adicionamos os eventos JavaScript MouseOver e MouseOut para cada linha, e o evento atribui a classe CSS adequada ao evento: troca a cor quando repousamos o mouse na linha e volta à cor original quando retiramos o mouse da mesma.
E agora, e a seleção com clique na linha?
Do jeito que está, para editarmos um registro precisamos clicar no botão Editar da linha correspondente e fazer alguma ação (redirecionar para outra página ou abrir um modal). Para fazermos a seleção com o clique na linha, iremos atribuir no evento onClick de cada linha a função JavaScript que realiza o postback do botão Editar.
Porém deixaremos este botão invisível, colocando Visible = false no botão btnEditar. Vamos direto à técnica de transferência da função do botão para a linha!
Para isso, sobreescreva o método Render da página e coloque o seguinte código:
1: protected override void Render(HtmlTextWriter writer)
2: {
3: //Aqui vamos tornar cada linha do grid gvDados clicável: quando clicarmos nela, será executado o código do botão Editar
4: foreach (GridViewRow r in gvDados.Rows)
5: {
6: for (int i = 0; i < r.Cells.Count - 1; i++)
7: {
8: r.Cells[i].Attributes.Add("onClick", ClientScript.GetPostBackClientHyperlink(r.FindControl("btnEditar"), "", true));
9: }
10: }
11: base.Render(writer);
12: }
O método GetPostBackClientHyperlink retorna a função JavaScript responsável pelo postback do controle passado no primeiro parâmetro. O segundo parâmetro é o argumento da função, que pode ser passado vazio e o terceiro indica se queremos validar este evento para execução. Como estaremos executando um evento pertencente a um controle invisível (= não é renderizado no HTML de saída), precisamos validá-lo para o ASP.NET reconhecê-lo.
Varremos cada linha do grid, e dentro do laço dessa varredura varremos cada célula. Ele adicionará a URL de postback do botão btnEditar a cada célula da linha menos na última, explico: na última linha célula ficará o botão de Excluir. Se associarmos o evento na linha inteira, ao clicarmos no botão Excluir também executaremos o btnEditar, o que não queremos.
Agora, vamos para a rotina de seleção do registro e a abertura do mesmo dentro da janela modal, destacando no grid a linha do mesmo. Observe o código do evento onClick do botão Editar:
1: protected void btnEditar_Click(object sender, EventArgs e)
2: {
3: //Seta a linha selecionada com a classe CSS para destacá-la e guarda seu índice em uma variável auxiliar (no viewstate da página)
4: gvDados.Rows[Int32.Parse((sender as Button).CommandArgument)].CssClass = "selected";
5: ViewState["AUX"] = (sender as Button).CommandArgument;
6:
7: //Coloca o método do botão Salvar em modo de Atualização
8: ViewState["SALVAR"] = "U";
9:
10: //Obtém a(s) chave(s) do registro através do índice da linha do gridview (por isso, é importante SEMPRE setar os DataKeyNames!)
11: int key = Int32.Parse(gvDados.DataKeys[Int32.Parse((sender as Button).CommandArgument)].Value.ToString());
12:
13: ...//Carregue o registro nos textboxes...
14:
15: //Faz aparecer a janela Modal e esconder o div do AJAX, senão a consequencia é desagradável!
16: ScriptManager.RegisterStartupScript(this, this.GetType(), "abremodal", "$dvModalLoader.jqmHide();$dvDetalhes.jqmShow();", true);
17: }
Como passamos o índice da linha do grid no CommandArgument do botão Editar, usaremos este atributo para selecionar a linha e atribuiremos a classe CSS "selected" na mesma. Em seguida, guardamos o mesmo índice em algum outro lugar para voltar para a classe CSS "normal", por exemplo, ao salvar ou cancelar as alterações. Com isso, a janela modal é aberta e a linha é destacada no gridview :-)
Veja vídeo com o exemplo:
Postei somente a primeira parte da vídeo-aula correspondente aqui para não carregar demais a página. Segue links das partes restantes:
Exemplo de Gridview com mudança de cor e seleção de registros com clique na linha (33 KiB)
Abraços a todos!
2 comentários:
Muito bom esse teu post em cara, estava me matando pra descobrir como controlar esses eventos que faziamos com javascript, sem mexer no código web, e nos outros tutorias só me falavam que eu teria que usar o javas script, mas não falavam onde e nem como. Mas aqui nem precisei terminar de ler o tutorial todo, que eu já achei o que queria.
Valeu pela ajuda.
@Anônimo:
Pois é, outras coisas que podemos fazer via JavaScript já me pouparam reclamações... por exemplo, autopostback de comboboxes para exibir/ocultar divs: quando eu fazia isso via código web no servidor era uma lentidão...
Que bom que isso te ajudou!
Abraços!
Postar um comentário