Introducción
El objetivo del artículo apunta a demostrar como implementar la búsqueda de un determinado ítem haciendo uso de ventanas que se abran en popup.
Para implementarlo se hará uso de la librería jquery UI, la cual incluye funcionalidad para crear cuadros de dialog modales.
El código fue implementado de dos formas distintas, si bien son muy parecidas tienen sutiles cambios, estas dos formas las denomine:
- Selección con evento (usando un ImageButton)
- Selección sin evento (usando el tag html <img>)
Imagino se preguntaran del porque de esta diferencia del uso de un evento o no, básicamente difieren en el uso de controles asp.net (con evento) o tag de html (sin evento), cada alternativa cambia la forma en que se implementa la solución, en concreto la forma en que se toma el ítem elegido.
Empezaremos analizando la parte de la implementación que es común en ambos casos para luego ir a los detalles que afectan el usar un control de asp.net o uno de html
Abrir ventana de filtro
La definición de la ventana por medio de jquery UI solo implica asociar al <div> que representara el dialog
$(function() {
$('#btnOpenSupplierSearch').click(function() {
registerGridEvent();
$('#dialog').dialog('open');
});
$('#dialog').dialog({
autoOpen: false,
modal: true,
width: 700,
heigth: 250,
title: 'Buscar Proveedor',
buttons: {
"Cancel": function() {
$(this).dialog("close");
}
}
});
});
En este caso será por medio de una acción del botón de búsqueda que se abrirá la ventana.
Selección sin evento (usando html <img>)
Es muy importante en este punto notar como se asocia el <img> que representa la selección de cada row del grid con su correspondiente acción en javascript.
En esta acción desde javascript no solo se toma la información del html, sino que además se cierra el dialog y se lanza el evento de búsqueda accionado el botón que tiene esta funcionalidad.
function registerGridEvent() {
$('#<%=gvSuppliers.ClientID %> .imgSelection').click(function() {
var supplierID = $(this).attr('SupplierID');
var tr = $(this).parent().parent();
var companyName = $('td:eq(2)', tr).text();
//asigno datos a los controles
$("[id*='txtId']").val(supplierID);
$("[id*='lblSupplierName']").text(companyName);
//cierro el popup de seleccion
$('#dialog').dialog("close");
//aplico el filtro
$("[id*='btnFiltrar']").click();
})
}
Re-asignación de evento jquery
Existe un punto de conflicto entre los eventos de asp.net y jquery, espacialmente cuando se usa el UpdatePanel para conservar los eventos y se mezclan acción de jquery.
Estos dos mundos no se llevan muy bien, un claro ejemplo se podría apreciar con el paginado del gridview, si bien al ir cambiando de pagina no se nota el refresco ya que el UpdatePanel lo hace simple, por debajo se genera una invocación al servidor para ejecutar del evento asociado al grid.
protected void gvSuppliers_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gvSuppliers.PageIndex = e.NewPageIndex;
LoadGridSuppliers();
//
// registro el evento click del boton, ya que al pagina el postback
// quita la asociacion del evento que jquery
//
string script = "registerGridEvent();";
ScriptManager.RegisterClientScriptBlock(this, typeof(Page), "registerevent", script, true);
}
Jquery se ve afectado si es que en ese bloque se tenia eventos asociados en algún tag, en este caso concreto el tag <img> esta asociado al evento click() de jquery, por lo tanto hay que volver a re-asociar para que se revalide la acción.
Es por eso que en el evento de paginado en el server se lanza la acción en el cliente por medio del
ScriptManager.RegisterClientScriptBlock()
Esto es necesario para que a la vuelta del postback se ejecute la function javascript y asigne nuevamente el evento click() de jquery al selector definido.
Selección con evento (uso control asp.net ImageButton)
En este caso el camino tiene algunas vueltas entres server y cliente:
De la acción del ImageButton se ingresa al evento SelectedIndexChanged en el código .net, quien luego de tomar la información del gridview armara el script que asignara la info, cerrando el dialogo y por ultimo lanzando la acción de botón para filtrar los productos.
protected void gvSuppliers_SelectedIndexChanging(object sender, GridViewSelectEventArgs e)
{
int supplierId = Convert.ToInt32(gvSuppliers.DataKeys[e.NewSelectedIndex].Value);
string companyName = gvSuppliers.Rows[e.NewSelectedIndex].Cells[2].Text;
string script = @"$(function(){{
SupplierSelected('{0}','{1}');
}});"; //se define {{ para poder usar el string.Format()
script = string.Format(script, supplierId, companyName.Encode());
ScriptManager.RegisterStartupScript(Page, typeof(Page), "popupclose", script, true);
}
function SupplierSelected(supplierID, companyName) {
$("[id*='txtId']").val(supplierID);
$("[id*='lblSupplierName']").text(companyName);
//cierro el popup de seleccion
$('#dialog').dialog("close");
//aplico el filtro
$("[id*='btnFiltrar']").click();
}
Un punto que no hay que pasar por alto que afecta al evento del control dentro del dialog, jquery reasigna las acciones del dialogo a nivel del body y no del form, por eso línea cambia esa acción de esta forma los eventos de asp.net se habilitan nuevamente.

Código
| [C#]
|















