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 la implementación se utilizara la funcionalidad de window.open() provista por javascript.
El ejemplo consiste en un listado de producto, pudiendo ser filtrados mediante una ventana popup que lista los proveedores.
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
- Selección sin evento
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 búsquedaLa definición del botón de búsqueda se logra adjuntando el evento click de jquery al tag <input>, como se refleja en la imagen
Esta acción lanzara la ventana de búsqueda que se ha implementado mediante el uso de window.open()
Filtro de productos
Una vez seleccionado el proveedor en la ventana de búsqueda esta acciona, o ejecuta, el botón de filtro, el cual se ha implementado, en en la pagina original, es decir la ventana hija invoca un boton en la ventana padre.
protected void btnFiltrar_Click(object sender, EventArgs e) { LoadGridProducts(); // // muestro la descripcion del proveedor // Suppliers supplier = NorthwindData.GetSupplierById(txtId.Text); string CompanyName = ""; if (supplier != null) { CompanyName = supplier.CompanyName.Encode(); } // // asigna el nombre al label que esta fuera del updatepanel // string script = @"$('#{0}').text('{1}');"; script = string.Format(script, lblSupplierName.ClientID, CompanyName); ScriptManager.RegisterStartupScript(this, typeof(Page), "filterinfo", script, true); }
private void LoadGridProducts() { int? SupplierId = null; int id = 0; if (Int32.TryParse(txtId.Text, out id)) { SupplierId = id; } gvProducts.DataSource = NorthwindData.GetProductsBySupplier(SupplierId); gvProducts.DataBind(); }
Algo que quizás no parezca tener sentido al principio es porque el nombre del proveedor seleccionado es asignado mediante código javascript (o mejor dicho jquery), en lugar de hacerlo directamente, bueno esto se deba al uso del control UpdatePanel, el label donde se asigna el nombre del proveedor seleccionado esta por fuera del panel lo cual requiere que al asignar un valor sea realice de forma indirecta.
Selección sin evento (usando html <img>)
Empezaremos analizando como realizar la selección usando un control simple de html, en este caso en el grid de proveedores se usa el tag <img> dentro del item template
Pro medio de la ayuda de jquery se asocia el evento click, usando el atributo class del <img> como selector
<script type="text/javascript"> $(function() { $('#<%=gvSuppliers.ClientID %> .imgSelection').click(function() { var supplierID = $(this).attr('SupplierID'); var tr = $(this).parent().parent(); var companyName = $('td:eq(2)', tr).text(); window.opener.$("[id*='txtId']").val(supplierID); window.opener.$("[id*='lblSupplierName']").text(companyName); window.opener.$("[id*='btnFiltrar']").click(); window.close(); }) }); </script>
Como el evento lo lanza el propio tag <img> se puede acceder a este mediante $(this) tomando el atributo, pero para recuperar información adicional debe subirse hasta el tag <tr> de la tabla que genera el gridview para así poder acceder a los datos de las celdas, el td:eq(2), hace referencia a la segunda columna del grid
La integración de jquery con javascript nos permite realizar una búsqueda en la página padre usando window.opener, y mediante el *= sobre el id, una búsqueda aproximada, similar a usar el like.
en las ultimas dos líneas se lanza el evento click del boton de filtro y se cierra la ventana.
Selección con evento (uso control asp.net ImageButton)
A diferencia del caso sin evento, en este se hace uso de un control de asp.net para seleccionar el proveedor del grid, como se puede observar en la imagen
Este simple cambio impacta en la forma en que se implementa el resto
<script type="text/javascript"> function SupplierSelected(supplierID, companyName) { window.opener.$("[id*='txtId']").val(supplierID); window.opener.$("[id*='lblSupplierName']").text(companyName); window.opener.$("[id*='btnFiltrar']").click(); window.close(); } </script>
El javascript usado se reduce, ya no se implementa la búsqueda en al tabla del html que genera el gridview, pues se dispone acceso directo al control desde código .net
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); }
La asignación del valor de retorno no es tan directa, sino que debe ser escrita en el retorno del postback del evento, esto es necesario ya que el window.opener solo puede usarse desde código cliente.
Código
[C#]
|