Wednesday, March 28, 2012

ViewState and JavaScript

Hi, I posted this in another forum, and I am hopping I'll get more response here.

I have two list boxes that I use for dual list box functionality, and there are four buttons that allow movement of the items from one box to another. All this is performed using javascript functions attached to buttons those 4 buttons. There is one more button that is supposed to get values from the right box and print reports. All controls are in update panel. In Pre-Reneder method I am checking to see if there are any items in the right box, and there aren't ever any. Is there something that I need to do so state of the controls would be maintained?

Here is the javascript

function MoveDualList( srcListId, destListId, moveAll )

{

var srcList = document.getElementById(srcListId);

var destList = document.getElementById(destListId);

// Do nothing if nothing is selected

if ( ( srcList.selectedIndex == -1 ) && ( moveAll ==false ) )

{

return;

}

newDestList =new Array( destList.options.length );

var len = 0;

for( len = 0; len < destList.options.length; len++ )

{

if ( destList.options[ len ] !=null )

{

newDestList[ len ] =new Option( destList.options[ len ].text, destList.options[ len ].value, destList.options[ len ].defaultSelected, destList.options[ len ].selected );

}

}

for(var i = 0; i < srcList.options.length; i++ )

{

if ( srcList.options[i] !=null && ( srcList.options[i].selected ==true || moveAll ) )

{

// Statements to perform if option is selected

// Incorporate into new list

newDestList[ len ] =new Option( srcList.options[i].text, srcList.options[i].value, srcList.options[i].defaultSelected, srcList.options[i].selected );

len++;

}

}

// Populate the destination with the items from the new array

for (var j = 0; j < newDestList.length; j++ )

{

if ( newDestList[ j ] !=null )

{

destList.options[ j ] = newDestList[ j ];

}

}

// Erase source list selected elements

for(var i = srcList.options.length - 1; i >= 0; i-- )

{

if ( srcList.options[i] !=null && ( srcList.options[i].selected ==true || moveAll ) )

{

// Erase Source

srcList.options[i] =null;

}

}

//sort destinantion list box

SortListBox(destList,compareText)

}// End of moveDualList()

function compareText (opt1, opt2)

{

return opt1.text.toLowerCase() < opt2.text.toLowerCase() ? -1 :

opt1.text.toLowerCase() > opt2.text.toLowerCase() ? 1 : 0;

}

function SortListBox (pListBox, compareFunction)

{

if (!compareFunction)

{

compareFunction = compareText;

}

var options =new Array (pListBox.options.length);for (var i = 0; i < options.length; i++)

{

options[i] =new Option ( pListBox.options[i].text,

pListBox.options[i].value,

pListBox.options[i].defaultSelected,

pListBox.options[i].selected );

}

options.sort(compareFunction);

pListBox.options.length = 0;

for (var i = 0; i < options.length; i++)

{

pListBox.options[i] = options[i];

}

}

Hi,

ListBoxes do not post their values when HTML form is submitted. ListBoxes do only post their selected values. Therefore, any items added to the list box on the client are not available on the server. Your page restores list boxes from the viewstate encoded in the hidden field at the server and it doe not know anything about changes made to your listboxes on the lcient.

As a simple solution, I can suggest you placing a hidden field for your list box on the client and every time you change list box on the client, place a comma separated list of value into that hidden field. Then at the server, you can retrieve coma seperated list of values and populate your list (if you still need to render the same page) or process items.

-yuriy
http://couldbedone.blogspot.com

ViewState and JavaScript

Hi guys,

I have two list boxes that I use for dual list box functionality, and there are four buttons that allow movement of the items from one box to another. All this is performed using javascript functions attached to buttons those 4 buttons. There is one more button that is supposed to get values from the right box and print reports. All controls are in update panel. In Pre-Reneder method I am checking to see if there are any items in the right box, and there aren't ever any. Is there something that I need to do so state of the controls would be maintained?

Are you adding the Right side listbox items in client side by JS/DHTML? If so the viewstate will not sync with the server.


Yes I am using javascript/dhtml. So is there other way to do it on client side that will sync up with server?


Hi

I'm afraid there is no way to do this.Please change it to using AJAX to do that at server side.

Good luck.


Hi,

Please refer to this article[ http://aspalliance.com/1071_Smart_ListControl_in_ASPNET_1x20 ], it explains the reason and gives a solution.

Hope this helps.

ViewState in Session is still uploaded after AsyncPostBack

Hi all,

Here is the basic setup of my page.

- ViewState stored in session
- AutoCompleteExtender using a WebService
- UpdatePanel triggered by button next to AutoComplete TextBox

Here is the behavior I'm experiencing (note that I have validated this with Fiddler):

Page loads first time. "id="__VIEWSTATE" value="y0V/cubnEZ1qzAvIgW0oRpVSc8AvJU6rtssTVFt7+B8="
ViewState is short as expected because storing it in the session.

Now, I click on the button to activate the UpdatePanel, causing a partial postback. This takes much longer than expected. After inspecting with Fiddler I see that it is uploading 50K. I inspect the Request and notice that most of it is my ViewState (I have a repeater on the page). I even turned EnableViewState off on the Repeater and it still uploads it.

My questions are:

1. Where is this uploaded ViewState coming from? It was not downloaded, is it generated clientside by JavaScript?
2. How can I stop this ViewState from being uploaded?

Regards,
Cole

I now realize this is not the viewstate but all of the form elements names & values being concatenated together. Is there a way to adjust what gets sent back from the controls on a AsyncPostBack?


The only way I'm aware of is to not use updatepanels to traffic your info, but instead to use web services, page methods, or hand-jam your own webrequest.

ViewState Management Problem

hi

every one using ajax knows that viewstate problem exists in it.....

is there any remedy available for that problem???

Could you please be more specific about what problems you're refering to?

Thanks,

Eilon

ViewState of CollapsiblePanelExtender

I have several collapsible panels on a web form, and I cant seem to get them to remember their viewstate. Am I missing something or is this not possible?

Here is an example:

<asp:Content ID="Content2" ContentPlaceHolderID="DetailContentPage" Runat="Server"><div style="margin-left:10px"> <asp:Panel Width=100% ID="mainPanel" runat=server > <table width=100% align="left" cellspacing=0 cellpadding=10 > <tr> <td> <asp:Panel ID="ResHeaderPanel" runat="server" CssClass="formPanelHeader" Height="32px"> <div style="padding:5px; cursor: pointer;" > <div style="float:left; margin-top:4px;"> <asp:Image ID="imgResArrow" runat="server" ImageUrl="~/images/expand.jpg"/> </div> <div style="float:left; margin-left:6px; vertical-align:middle;">Engine Settings</div> <div style="float:left; margin-left:30px; margin-top:4px; font-size:x-small" > <asp:Label ID="lblResHeaderHint" runat="server">(Show Details...)</asp:Label> </div> </div> </asp:Panel> <asp:Panel ID="ResPanel" runat="server" CssClass="formPanel"> <table> <tr> <td width=200px>Number of Rooms:</td> <td width=70%><asp:TextBox ID="txtNumRooms" runat="server" MaxLength=200 width=70% /></td> </tr> <tr> <td>Time Zone: </td> <td><asp:TextBox ID="txtTimeZone" runat=server MaxLength=200 width=70%/></td> </tr> <tr> <td>form controls removed </td> <td></td> </tr> <tr> </table> </asp:Panel><!-- ******************************** --> <asp:Panel ID="ContactheaderPanel" runat="server" CssClass="formPanelHeader" Height="32px"> <div style="padding:5px; cursor: pointer;" > <div style="float:left; margin-top:4px;"> <asp:Image ID="Image1" runat="server" ImageUrl="~/images/expand.jpg"/> </div> <div style="float:left; margin-left:6px; vertical-align:middle;">Contact Details</div> <div style="float:left; margin-left:30px; margin-top:4px; font-size:x-small" > <asp:Label ID="lblContactHeaderHint" runat="server">(Show Details...)</asp:Label> </div> </div> </asp:Panel> <asp:Panel ID="ContactPanel" runat="server" CssClass="formPanel"> <table> <tr> <td width=200px>Address:</td> <td width=70%><asp:TextBox ID="txtAddress1" ReadOnly=false runat="server" MaxLength=200 width=70% /></td> </tr> <tr> <td>Address: </td> <td><asp:TextBox ID="txtAddress2" runat=server MaxLength=200 width=70%/></td> </tr> <tr> <td>form controls removed </td> <td></td> </tr> </table> </asp:Panel> </td> </tr> </table> <ajx:CollapsiblePanelExtender ID="cpeRes" runat="Server" TargetControlID="ResPanel" ExpandControlID="ResHeaderPanel" CollapseControlID="ResHeaderPanel" TextLabelID="lblResHeaderHint" ExpandedText=" " CollapsedText="(Click to Show Details...)" ImageControlID="imgResArrow" ExpandedImage="~/images/collapse.jpg" CollapsedImage="~/images/expand.jpg" EnableViewState=true SuppressPostBack="true" /> <ajx:CollapsiblePanelExtender ID="cpeContact" runat="Server" TargetControlID="ContactPanel" ExpandControlID="ContactHeaderPanel" CollapseControlID="ContactheaderPanel" TextLabelID="lblContactHeaderHint" ExpandedText=" " CollapsedText="(Click to Show Details...)" ImageControlID="imgContactArrow" ExpandedImage="~/images/collapse.jpg" CollapsedImage="~/images/expand.jpg" EnableViewState=true SuppressPostBack="true" /> </asp:Panel></div></asp:Content>
 
 
 -Steve 


I'm assuming your saying that when you open one, the other one closes. If so, try this: remove the "EnableViewState=true" from your code and wrap the entire thing in an update panel. I have similar yet I have no troubles with it but mine is wrapped in an update panel.


Thanks for the reply,

That is not quite what I was aiming for. I just wanted the state (open or closed) of the panels to be preserved after postbacks and navigation in my application.

I have a large form, that fills even a high res screen, I split the form into several collapsible panels, so that the user can show and hide the sections that are interesting. Then as the user navigates application records, and postbacks occur, I wish the state of each panel to be preserved.

Maybe I need to manually store the state to the Session and I am misunderstanding the scope of view state?


-Steve


If I understand correctly the panels are closed when you do a postback. This is because a postback reloads the controls. You want to do a partial postback, not a full postback. Therefore, wrap everything in an UpdatePanel, set the updatepanel's updatemode="conditional" and set the ScriptManager to enablepartialrendering="true"

This will cure the headache of a postback. Also with navigation it will have to be in updatepanels. Anything that does a postback must be eleminated and moved into the AJAX portion using update panels and such, otherwise the page will do a complete postback. Overall, the logic behind how things are to be setup with AJAX is a bit more work but the results is well worth it.

^_^


Thanks for the advice, this is the effect that I want to acheive, however I am using a Master page with content pages, linked to a site map based navigation. I trawled the web and could find no examples of the kind of site templete being used with AJAX.

Do have any advice for trying to achieve this? Otherwise the best solution would be to store the panels state to the Sessions, although this seems clunky and I would have thought that the controls would respect viewsate acress postbacks.

-Steve

Viewstate problem

hi

every one using ajax knows that viewstate problem exists in it.....

is there any remedy available for that problem???

What problem? If you use Atlas, its updatepanel will go back to the server and runs the page as it normally would, and send/get ViewState per update as well, I didn't see any problem~
when using the back button and front button u ll be not able to maintain the viewstate........

Ya.. this is true.. as commn;y ajax calls leave no histtory in browsers..

Here is a back button support.. works with the old ctp...

viewstate serialization and atlas

Just testing a little popup calendar user control making use of Atlas. I notice that when I serialize the viewstate unusually (I have a 'StorePage' class that stores the viewstate in the db, keyed on a GUID in a hidden field on the page), the atlas calendar popup fails.

Can I work around this? Do my Atlas pages need to be decended directly from the Page class, or is my GUID-keyed technique flawed?

The calendar uses an updatepanel.

Thanks,

John

Hi John,

Can you explain exactly what doesn't work? Are you registering the hidden field by using ClientScript.RegisterHiddenField?

All pages no matter what will derive from Page, and Atlas doesn't care if there are other intermediate classes in the way (almost all pages have intermediate classes anyway due to code-behind files).

I can't think of any specific reason why this wouldn't work off the top of my head.

Thanks,

Eilon