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#]
|
Buscando cómo solucionar el problema de la paginación de un GridView he dado con tu blog que me parece una pasada.
ResponderEliminarMuchas gracias y lo anoto al reader ;-)
Muy bueno, pero tendras el codigo para vb.net?
ResponderEliminarMuchas gracias
muy bueno ya me las arregle para vb.net que no era nada de cambios, ahora como puedo pasar parametros desde esa llamada a mi otra ventana qu se abre?
ResponderEliminarhola David
ResponderEliminarno entendi, que otra ventana se abre ?
o sea tienes la ventana padre, que es la principal y la ventana hija, no hay otra
simpre suas el window.opner para comunicar o sino defines datos en que querystring en la url de la pagina hija
saludos
Que tal Leandro, Tu Blog esta muy interesante, gracias por todo lo q aportas.
ResponderEliminarUna consulta cuando se abre la pagina con window.oper no se puede obtener acceso a los controles de la pagina previa con Page.PreviousPage?
hola OscMop
ResponderEliminares que al usar el window.open lo haces desde javascript por lo que no hay un postback
para acceder a los controles de la ventana padre lo haces desde codigo cliente usando el
window.opener
desde el servidor deberias enviar los datos en la url como parte del querystring, no viajan por post
saludos
Hola Leandro, ahora que el chrome ha quitado el showModalDialog esta solucion me parece buena opcion a menos que tengas otra... por otro lado como haria si la ventana hija lanza otra ventana como devolver datos de la segunda hija referenciando a la primera hija...
ResponderEliminargracias por tu respuesta y haber si tienes otra opcion por lo del showmodal dialog
hola Leandro,
ResponderEliminarya di con la solucion solo hay q referenciar el form de esta manera
window.opener.$("[id*='wfCuadroNecesidadBnd']");
sobre lo del retiro del chrome ojala haya otra opcion aparte de esta haber sorprendenos
saludos
buen día disculpa Leandro, están utilizando la Db de Northwindb
ResponderEliminarhola
EliminarSi asi es, es mas la db la tienes dentro de la carpeta App_Data
Es uan db de Sql Compact
saludos
buenas leandro tu depronto me podrias ayudar con una sesoria es que no pude desarrollar el ejemplo y lo necesito para un proyecto quedo atento a tu comentarios gracias
Eliminarbuen dia Leandro estoy tratando de hacer lo mismo pero no con windows forms habra alguna forma de hacer eso pero en web aplication, tendras un ejemplo de ello
ResponderEliminarhola
EliminarPodrias hacerlo si comunicas los forms como comento en el articulo
Comunicar Formularios
saludos
Leandro, buenas noches, estoy intentando aplicar este ejemplo, veo que en la página de los productos, al lado del botón buscar, tienes un txt, bien, no se si estoy leyendo mal el código, pero no veo que ese txt haga nada al momento de llamar el popup, entonces, mi idea es aplicar un doble filtro, es decir: Si escribe un texto en el campo y presiona buscar, pasar de alguna manera ese valor al aspx popup y que este valor filtre los registros mostrados en el grid, para que luego, al seleccionar un registro en el grid, aplique el filtro en el aspx padre, entonces, desconozco cómo pasar el valor del aspx padre al aspx popup por medio de Js, sí me puedes echar una mano... Agradecido...
ResponderEliminarHola Leandro, es un gusto saludarte, oye tengo una duda sobre tu ejemplo, ¿solo se puede realizar estas acciones desde la master page?
ResponderEliminar