📜 ⬆️ ⬇️

Pop-up modal windows on jQuery in ASP.NET

In this article I will talk about my experience in implementing a pop-up modal window with some form and submit-button on ASP.NET + jQuery and with the errors that I encountered.



At work, before starting to create a new project (web site), I decided to try switching from the client side of the Microsoft AJAX library to jQuery. There were several reasons for this, but this is not the point now.
')
It came to pop-up modal windows and it was necessary to find the appropriate plugin. At first I tried jqModal , but came across a bug in IE7 ( my bug report ). After that, I decided to use jQuery UI dialog , since I liked the jQuery UI library itself. Looking ahead, I will note that ThickBox has a similar problem to the one that I will now describe.

On the test site, I decided to implement a pop-up modal window for the user to enter the site. Those. when clicking on the link “Login”, a pop-up window ( modal ) with two text fields (email (as login) / password) and two buttons (ok / cancel) should appear.

Actually, I created a control that was supposed to ensure the appearance of this form when clicking on any links with the class “lbPopupLink”:

<% @ Control Language = "C #" AutoEventWireup = "true" Inherits = "Website.Controls.LoginBox" CodeBehind = "LoginBox.ascx.cs"%>
< asp: Panel runat = "server" ID = "panelMain" ToolTip = "Enter your email and password to access the site" >
< asp: Label runat = "server" ID = "Label1" AssociatedControlID = "txtEmail" CssClass = "req" Text = "Your email" > </ asp: Label > :
<Br />
< asp: TextBox runat = "server" ID = "txtEmail" AutoCompleteType = "Email" MaxLength = "255" > </ asp: TextBox >
< asp: RequiredFieldValidator runat = "server" ID = "RequiredFieldValidator1" ControlToValidate = "txtEmail" Display = "Dynamic" ErrorMessage = "You must enter an email." > </ asp: RequiredFieldValidator >
<Br />
<Br />
< asp: Label runat = "server" ID = "Label2" AssociatedControlID = "txtPassword" CssClass = "req" Text = "Password" > </ asp: Label > :
<Br />
< asp: TextBox runat = "server" ID = "txtPassword" TextMode = "Password" MaxLength = "255" > </ asp: TextBox >
< asp: RequiredFieldValidator runat = "server" ID = "RequiredFieldValidator2" ControlToValidate = "txtPassword" Display = "Dynamic" ErrorMessage = "You must enter a password." > </ asp: RequiredFieldValidator >
<Br />
<Br />
< asp: CheckBox ID = "chkRememberMe" runat = "server" Text = "remember me." />
<Br />
<Br />
< asp: Literal ID = "strError" runat = "server" EnableViewState = "False" > </ asp: Literal >
<Br />
< asp: Button ID = "butOk" runat = "server" Text = "Login" OnClick = "butOk_Click" />
< asp: Button ID = "butCancel" runat = "server" Text = "Cancel" CausesValidation = "false" />
</ asp: Panel >
< script type = "text / javascript" >
$ ( document ) .ready ( function ()
{
$ ( "# <% = this.panelMain.ClientID%>" ) .css ( "display" , "block" );
$ ( "# <% = this.panelMain.ClientID%>" ) .dialog
({
autoOpen: false ,
modal: true
width: 400,
height: 300,
dialogClass: "popupDialog" ,
resizable: false ,
overlay: {opacity: 0.5, background: "black" }
});

$ ( ".lbPopupLink" ) .click ( function ()
{
$ ( "# <% = this.panelMain.ClientID%>" ) .dialog ( "open" );
$ ( "# <% = this.txtEmail.ClientID%>" ) .focus ();
return false ;
});

$ ( "# <% = this.butCancel.ClientID%>" ) .click ( function ()
{
$ ( "# <% = this.panelMain.ClientID%>" ) .dialog ( "close" );
return false ;
});
});
</ script >
* This source code was highlighted with Source Code Highlighter .


(do not forget that I write the javascript code directly on the page, which, in principle, is not good, because if I put the control on the page twice, I get duplicate javascript code - in this case it is better to use ClientScriptManager.RegisterClientScriptBlock ; but since this control I was exactly going to use only once per page and in order to simplify the article I will leave everything as it is)

Everything worked, but not to the end: when you clicked on the link with the class “lbPopupLink”, a window really appeared, but when you clicked on the “Ok” button, nothing happened. Understanding and chatting with the developers of jQuery UI, I understood what was going on: to overcome glitches with z-index and stacking in IE when displaying the jQuery UI dialog dialog while displaying the window moves it inside the DOM to the very bottom of the page, placing it right at the end of <body>. Usually on other platforms this was not noticed, because just for each such “pop-up” form, it was done framing <form> with the necessary action and everything worked. But in the ASP.NET <form> ideology there should be only one element. It turned out that our form with <input type = "submit" value = "Ok" ... /> was transferred beyond the limits of a single form and therefore clicked on the "Ok" button did nothing. This can be read in my correspondence with the developers . In this correspondence, they (the developers) themselves proposed several temporary solutions and I implemented one of them: when you click on "Ok", the dialog is cloned before being destroyed and inserted back into the ASP.NET form (id = "aspnetForm"). For the sake of what was written a small function. There was still one “joke” with IE: it turned out that when using jQuery.clone in IE, the values ​​of <input type = "password" ... /> fields are not copied, so they had to be "handled". Actually, the function itself (do not kick - I work weekly on jQuery):

// Global variables
var __passwordCloneValues;

//
// Function of the jQuery UI dialog
// Should be applied to the dialog.
//
// Arguments:
// butOkId - id of the submit button
//
$ .fn.extend ({
dialogCloseAndSubmit: function (butOkId)
{
if (! Page_IsValid)
return false ;

__passwordCloneValues ​​= new Array ();
$ ( ": password" , $ ( this )). each ( function ()
{
__passwordCloneValues.push ($ ( this ) .val ());
});
__passwordCloneValues ​​= __passwordCloneValues.reverse ();

var dlg = $ ( this ) .clone ();
$ ( this ) .dialog ( "destroy" ) .remove ();

dlg.css ( “display” , “none” );
$ ( "Form: first" ) .append (dlg);
$ ( ": password" , dlg) .each ( function ()
{
$ ( this ) .val (__ passwordCloneValues.pop ());
});
$ ( "#" + butOkId, dlg) .click ();

return true ;
}
});
* This source code was highlighted with Source Code Highlighter .


And here’s what we need to supplement our javascript block from the beginning of the article to use this function:
$ ( "# <% = this.butOk.ClientID%>" ) .click ( function ()
{
return $ ( "# <% = this.panelMain.ClientID%>" ) .dialogCloseAndSubmit ($ ( this ) .attr ( "id" ));
});
* This source code was highlighted with Source Code Highlighter .


Here is what happened:


The source code of the entire test project .

PS: damn, for the first topic on Habré wanted shorter: |

Source: https://habr.com/ru/post/40221/


All Articles