Muchas veces porque queda muy agradable a la vista, es conveniente abrir una ventana (popup) con información adicional sobre un ítem deseado. Otro caso (particularmente el que me tocó desarrollar) puede ser hacer una especie de Wizard donde las ventanas cumplan una suerte de varios pasos donde se pueda ir para atrás,adelante y/o finalizar, al mejor estilo instalación de cualquier soft (siguiente,siguiente,siguiente,instalar…finalizar).
Lo que voy a mostrar parte de una pagina Principal (Pagina Madre) que es la que va a abrir el popup y acá se pueden usar 2 maneras, una ventana modal o una ventana modeless.
ventana modal: Este tipo de ventanas no permite la interacción con la ventana anterior mientras este abierta, de hecho interrumpe cualquier ejecución que se este haciendo por atrás. Por ejemplo si nosotros hacemos un postback y en el servidor abrimos una ventana con el método de JS window.showModalDialog puede ocurrir que la pagina madre quede en blanco o a medio cargar.
ventana modeless: Estas ventanas si permiten la interacción con su ventana madre, de hecho es posible hacer click en la ventana de atrás y lo va a permitir. Por lo comentado arriba este tipo modal puede ser útil. Pero si por ejemplo vamos a abrir una modal de una fila en un gridview que tiene un enlace a eliminarlo, si lo hace mientras esta la modeles abierta se lo va a permitir.
Este ejemplo esta diseñado para IE 6.0 en adelante y voy a usar VS2005. Básicamente voy a hacer esto:
Voy a usar una sola pagina como Wizard pero pueden ser las que se necesiten, al fin y al cabo todas terminan en un pagina de Fin.
La pagina principal va a contar con script porque va a mantener una variable para poder tomarla al final:
<script> var Guardar; function DeseaGuardar() { window.document.Form1.txtOculto.value=Guardar; __doPostBack('lnkGuardar',''); } function Ejecutar() { //Agregamos el JS para pasar el parametro var param=''; param='valor=' + window.document.Form1.TextBox1.value; WizardGeneral(200,550,'Default2.aspx',param); } </script>
La función WizardGeneral esta en un JS que adjunto con todo el proyecto al final y es la que arma la URL para abrir el Wizard de una manera u otra (Modal/Modeless) . Yo lo hago con una función en el evento onclick llamando a Ejecutar pero por ejemplo si queremos hacer popups de una grilla agregándole a todas las rows solo vamos a necesitar el ID de cada row para levantar los datos en el popup con lo cual se puede hacer todo en la 1era carga de la pagina agregando el id en el evento RowDatabound. Yo a modo de ejemplo solo modifico un textbox.
El HTML de la pagina sería algo así:
<HTML> <HEAD> <title>Prueba</title> <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR"> <meta content="Visual Basic .NET 7.1" name="CODE_LANGUAGE"> <meta content="JavaScript" name="vs_defaultClientScript"> <script language="javascript" src="JS/ScriptJS.js"></script> </HEAD> <body style="text-align: left"> <form id="Form1" method="post" runat="server"> <table> <tr> </tr> </table> <br /> <table width="100%"> <tr> <td style="text-align: center;" colspan="3"> <asp:Label ID="lblerror" runat="server" Width="100%"></asp:Label></td> </tr> <tr> <td style="width: 24px"> <asp:Label ID="Label1" runat="server" Text="Valor"></asp:Label></td> <td style="width: 60px"> <asp:TextBox ID="TextBox1" runat="server" Width="279px"></asp:TextBox> </td> <td style="width: 100px"> </td> </tr> <tr> <td style="width: 24px"> </td> <td style="width: 60px; text-align: center;"> <input id="btnBoton" type="button" value="Popup" runat =server /></td> <td style="width: 100px"> </td> </tr> </table> <br /> <asp:LinkButton ID="lnkGuardar" runat="server"></asp:LinkButton> <input id="txtOculto" style="width: 54px" runat =server type="hidden" /> </form> </body> </HTML>
Al final de la pagina hay 2 elementos importantes un Link, que es el que va a causar el postback de la pagina madre cuando termine el wizard y un hidden que es el que va a tener el valor de retorno del wizard.
El código de servidor es mas o menos este:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Introducir aquí el código de usuario para inicializar la página If Not Page.IsPostBack Then Try txtOculto.Value = "" btnBoton.Attributes.Add("onclick", "javascript:Ejecutar()") Catch ex As Exception lblerror.Text = ex.Message End Try End If End Sub Protected Sub lnkGuardar_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles lnkGuardar.Click 'txtOculto tiene el valor modificado que me devuelve el Wizard If Not String.IsNullOrEmpty(txtOculto.Value) Then TextBox1.Text = txtOculto.Value End Sub
Cuando la pagina de fin se cierre “cargar” de nuevo esta pagina ósea va a pasar por el page_load por eso hay que manejar bien el page.ispostback para no pisar valores y luego va a entrar por el click del Link que nosotros le formamos a hacer con la instrucción de Javascript __doPostBack.
La Pagina del Wizard tiene este HTML:
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Pagina del Wizard</title> <base target="_self"> </head> <body > <script language="javascript">1:2: var sData = dialogArguments;3: sData.Guardar= '';4: sData.DeseaGuardar();5: /*function cargarVentana ()6: {7: document.form1.TextBox1.value=window.dialogArguments;8: }*/9:10: function sourceCode() //Para ver el codigo fuente11: {12: d=window.open();13: d.document.open('text/plain').write(document.documentElement.outerHTML);14: }</script>
<form id="form1" runat="server" method="post">
<table>
<tr>
<td style="width: 100px">
<asp:Label ID="Label1" runat="server" Text="Valor del Wizard" Width="118px"></asp:Label></td>
<td style="width: 100px">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox></td>
</tr>
<tr>
<td style="width: 100px">
</td>
<td style="width: 100px">
<asp:Button ID="Button1" runat="server" Text="Ejecutar" /></td>
</tr>
<tr>
<td colspan="2">
<asp:Label ID="Label2" runat="server" ForeColor="#0000C0" Text="Al cambiar esta valor se modifica el textbox de la pagina principal"></asp:Label></td>
</tr>
</table>
</form>
</body>
</html>
Tiene algunas particularidades la primera es que tiene le atributo target= self esto es para cuando hacemos el response.redirect a la pagina de fin no nos abra una pagina sino que siga en la misma. Después la función Javascript toma el dialogArguments que son las variables o funciones de la pagina madre. Y por ultimo algo que nos puede ser muy útil para depurar es una función para ver el HTML de la pagina cuando se esta ejecutando, porque las modales no dejan hacer click derecho para ver el código. Simplemente se agrega el nombre (sourceCode) en el evento onload del Form y listo apenas carga la pagina tenemos una nueva ventanita con el HTML
.
Este es el código de servidor:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Try If Not Page.IsPostBack Then TextBox1.Text = Request.Params("valor") Else Dim strpage As String = "General_Fin_W.aspx" Dim paramFinal As String = "modo=modificacion&datos=".ToString + TextBox1.Text strpage += "?".ToString + paramFinal.ToString 'General_Fin_W.aspx?modo=modificacion&datos= Response.Redirect(strpage) End If Catch ex As Exception Response.Write(ex.Message) End Try End Sub
y por ultimo la pagina de Fin HTML y código de Servidor:
<html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <title></title> <script language="JavaScript" type="text/javascript">1:2: function CerrarWizard()3: {4: var sData = dialogArguments;5:6: //var datos= document.Form1.HiddenField1.value; // Esto vale lo que7: //termina concatenando en el wizard8: var datos= document.Form1.HiddenField1.value;9: sData.Guardar=datos;10: sData.DeseaGuardar();11: window.close();12: }13:14: function sourceCode() //Para ver el codigo fuente15: {16: d=window.open();17: d.document.open('text/plain').write(document.documentElement.outerHTML);18: }19:20:</script>
</head>
<body class="BodyNormal" onactivate ="CerrarWizard();">
<form id="Form1" runat="server" >
<div style="text-align: center" >
<asp:Label ID="lblMensajes" runat="server" CssClass="labelmensaje" Width="98%">Cargando ...</asp:Label><br />
<asp:HiddenField ID="HiddenField1" runat="server" /></div>
</form>
</body>
</html>
Tiene una simple pantalla blanca con un mensaje cargando…. (pero la idea es que prácticamente no aparezca) porque como se ve en la funcion hace en onload le asigna el valor a sData.Guardar (osea el valor oculto de la pagina madre) y despues hace un window.close.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Select Case Request.Params("modo") Case "modificacion" If Not String.IsNullOrEmpty(Request.Params("datos")) Then HiddenField1.Value = Request.Params("datos") End If End Select End Sub
La idea es hacer una sola pagina de fin en caso de que necesitamos varios Wizard por ejemplo para cargar Personas o Productos, etc. Todas devuelven 1 dato por ejemplo si son Wizard de Alta podrían devolver el ID a la pagina Madre para poder levantarlo desde ahí.
El proyecto completo esta aqui
Saludos.



Octubre 1, 2008 a las 12:33 am |
Tengo un problema tengo con una pagina asp.net que tiene una grilla, esta es llenada desde un popup en donde selecciono de una grilla las filas que quiero que se carguen en la grilla de la pagina que lo invoco, las filas seleccionadas son almacenadas en una variable sesion, es decir que al seleccionar las filas de la grillas del popup y cerrar el popup los datos son almacenados en un varible sesion y en el load de la pagina principal se llama al metodo para cargar la grilla, esto funciona en desarrollo, realizo el debug y la grilla de la pagina principal se carga pero cuando realizo el publish, en IIS6, y corro el aplicativo la grilla de pagina principal no muetsra los datos sino hasta que le doy F5, no se que pueda estar sucediendo, porfavor si me podria ayudar con este tema.
Febrero 9, 2009 a las 2:22 pm |
Soy muy novata en asp.net y quisiera que se abriera mediante un hiperlink un popup para mostrar texto adicional …
Febrero 9, 2009 a las 2:33 pm |
De la manera en que lo hago yo osea con esta sentencia:
btnBoton.Attributes.Add(“onclick”, “javascript:Ejecutar()”)
el hiperlink tambien se puede usar basta con cambiarla, en el pageload, a :
If Not Page.IsPostBack Then
miHyperLink.Attributes.Add(“onclick”, “javascript:Ejecutar()”)
End if
para que el hyperlink tenga la rutina de Javascript que abre la ventana.
Saludos
Septiembre 25, 2009 a las 10:44 pm |
mira yo tengo un problema segun el ejemplo de arriba lo e tratado de modificar para que trabaje con 2 forms solamente,de la siguiente manera:
-1 aspx que llame al popup
-2 el popup que retone los datos.
codigo Fuente :
Página sin título
var Guardar;
function DeseaGuardar()
{
window.document.form1.txtOculto.value=Guardar;
__doPostBack(‘Button1′,”);
}
function url()
{
// window.open(“Popup.aspx?USP=usp_get_Usuario”,
//”",”width=600,height=400,left = 50,position=relative”);
//Popup.moveTo(400,100);
var param=”;
param=’valor=’ + window.document.form1.TextBox1.value;
window.showModalDialog(“popup.aspx?”+param,window,”dialogHeight:50px; dialogWidth:70px;”);
}
————————
Defualt.aspx
———————–
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack==false )
{
txtOculto.Value = “”;
Button1.Attributes.Add(“onclick”, “javascript:url()”);
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txtOculto.Value) )
{
TextBox1.Text = txtOculto.Value;
}
}
———————————–
popup codigo fuente
———————————–
Página sin título
var sData = dialogArguments;
sData.Guardar= ”;
sData.DeseaGuardar();
function CerrarWizard()
{
var sData = dialogArguments;
var datos= document.form1.HiddenField1.value;
sData.Guardar=datos;
sData.DeseaGuardar();
window.close();
}
————————————-
popup.aspx
————————————-
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack == false)
{
TextBox1.Text = Request.QueryString["valor"];
}
else {
HiddenField1.Value = TextBox1.Text;
Response.Redirect(“Default.aspx”);
}
—————————————————–
—————————————————–
El error es que no devuelve el valor cambiado!
me sale error constantemente! bueno si alguien sabe la solucion espero respuesta x esta pagina o a mi correo
spike14_11@hotmal.com
Octubre 1, 2009 a las 1:47 pm |
Fijate en la pagina popup.aspx de redireccionar a la pagina de fin que explico al final. Esa es la que le vuelve a la pagina madre.
en popup.aspx podes hacer asi:
HiddenField1.Value = TextBox1.Text;
Response.Redirect(”Fin.aspx?datos=” & HiddenField1.Value );
y en la pagina de Fin.aspx tiene un HTML algo asi:
function CerrarWizard()
{
var sData = dialogArguments;
// Esto vale lo que
//termina concatenando en el wizard
var datos= document.Form1.HiddenField1.value;
sData.Guardar=datos;
sData.DeseaGuardar();
window.close();
}
—————————————–
Despues en el Fin.aspx.vb (o .cs):
If Not String.IsNullOrEmpty(Request.Params(“datos”)) Then
HiddenField1.Value = Request.Params(“datos”)
end if
——————————–
Algo así proba osea básicamente crear una pagina mas que no se va a ver porque solo recibe la ultima pagina del wizard y lo cierra enviando el parametro dato a la pagina madre.
Saludos
Octubre 21, 2009 a las 7:28 pm |
excelente muy buen tema, trate de bajar el archivo para poder reisarlo a ams detalle pero no sirve el enlace, me lopodrias mandar a mi correo por favor, te lo agradeceria mucho, me serviria bastante ya que soy nuevo en esto de los popup, por favor. mi correo es temocop@hotmail.com