JQuery BlockUI with UpdatePanel Viewstate Issue

2019-02-10 22:22发布

问题:

I am using BlockUI to show a modal. Within the blocked modal I have an update panel. Within the update panel I have a textbox and a button that submits the content back to the server. Everything works fine up to this point (the blockUI is called, the modal appears, and the button performs the postback). However, when the button's click event is fired the value for the textbox is consistently empty even if text was entered. When the update panel updates the textbox shows up blank. It appears that this may be some sort of viewstate issue and I haven't turned off viewstate.

<a href="javascript:$.blockUI({ message: $('#divTest') });">SHOW MODAL</a>

<div id="divTest" style="display: none;">
<asp:UpdatePanel ID="upTest" UpdateMode="Conditional" runat="server">
    <ContentTemplate>
        <asp:TextBox ID="txtTestVS" runat="server" /><br />
        <asp:Button ID="cmdTest" Text="TEST" OnClick="cmdTest_Click" UseSubmitBehavior="false" runat="server" />
    </ContentTemplate>
</asp:UpdatePanel>

SERVER-SIDE:

protected void cmdTest_Click(object sender, EventArgs e)

{ string x = txtTestVS.Text; }

String "x" always equal "".

回答1:

This is a common problem with dialog plug-ins, the problem is when content is put in the blockUI container, it's appended to the <body> element, and no longer in the form being submitted to the server. To solve this you need to edit the blockUI code a bit:

Here's the source: http://github.com/malsup/blockui/blob/master/jquery.blockUI.js

Change this:
Line 262: var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
to: var layers = [lyr1,lyr2,lyr3], $par = full ? $('form') : $(el);

and this:
Line 382: els = $('body').children().filter('.blockUI').add('body > .blockUI');
to: els = $('form').children().filter('.blockUI').add('form > .blockUI');

That should get you going and the textbox values coming through.



回答2:

The Problem

From my reading, here and elsewhere, apparently jQuery UI (upon dialog init) moves your dialog element (along with its contents) outside of the <form element and attaches it to the <body. Speculation is because a body is always present when a form is not and there might be some z-order benefits when IE is used.

The problem is that all ASP.NET controls are required by Microsoft to be in the <form of the page to participate in postback and to work right, whether or not they are actual HTML input controls.

A Solution (jQuery 1.4+)*: Programmatically move the dialog box inside the HTML Form:

(There are other answers similar to this. This is the shortest I've seen, taking only one line of code and doesn't require the jQuery source code to be modified.)

With jQuery UI 1.8.7 (Stable, for jQuery 1.3.2+) I've had success making ASP.NET controls maintain PostBack behaviour via the following "trick" derived from this forum thread:

// As is customary, call $mydialog.dialog(..) to initialize it.
// Init all your dialog boxes before continuing.

// After init, TYPE THIS LINE to move all dialog boxes back into the form element
$('.ui-dialog').detach().appendTo('form');

To target just one dialog box with the fix use this line instead:

$mydialog.closest('.ui-dialog').detach().appendTo('form');

where $mydialog is a reference to your dialog element by a jQuery selector -e.g. $('#mydiv').

The reason the class .ui-dialog is used is because jQuery UI wraps your dialog element in an outer div having the class name ui-dialog which is always on the outermost element of the dialog and is unique among all other class names used throughout the dialog. This means your actual dialog is constructed of more than just the html element you specified for it and you need to affect the entire dialog.

Upon dialog init, jQuery moves the constructed dialog outside the HTML form.
By inserting the given line, you move everything back into the form, making ASP.NET happy.

The detach jQuery method cuts it out of the DOM but maintains all jQuery events and data associated with it.
(* Because detach was introduced with jQuery 1.4, this solution is restricted to that version and higher. I've heard that older versions of jQuery might achieve limited success by using clone and remove instead although I haven't tried it.)

The appendTo jQuery method pastes it into the html form.

This is what I understand. Hope it helps somebody else.



回答3:

Should your first line of code be this instead:

<a href="javascript:$.blockUI({ message: $('#divTest').val() });">SHOW MODAL</a>

or

<a href="javascript:$.blockUI({ message: $('#divTest').text() });">SHOW MODAL</a>


回答4:

Make sure all the contents you wnat to update are inside update panel