Repopulating a dropdown outside an updatepanel - asp.net

Probably this is an ignorance of Async postbacks, so let me lob a softball out there.
I have three cascading dropdowns in an updatepanel, using these you can pick your Store->Department->Product. A fourth DDL sits outside the updatepanel, and using this you pick your competitor. Different stores match with different competitors. A gridview (also outside) then displays the join of Store->Department->Product->Competitor Price.
This works fine when you first load and if you switch to a different store that has the same competitor. But if you change the updatepanel DDLs to a store that does not share the chosen competitor and click "Display" (causing a PostBack), I get an "Invalid Postback or callback argument." If I remove the Competitor DDL and hardcode the gridview's competitor, the error goes away and I can navigate with abandon.
Why won't that fourth DDL repopulate on postback? How do I fix this problem?

The reason is that in the latter case on change of Store->Department->Product if you are rebinding the Competitior DropDownlist then ListItems will change on the server but will not be rendered to the client because it is not inside any updatepanel and thus the Competitior DropDownlist has old values in it.
when the Postback occurs ASP.Net will not understand how these old values came and will throw "Invalid Postback or Callback argument" error.
Best way to solve this will be place your dropdownlist (and gridview) inside an updatepanel.

Related

Items in a Repeater are lost during a postback (callback)

Using ASP.NET 4.0 WebForms.
I have a repeater with checkboxes in it. The repeater and checkboxes have viewstate enabled. There's a button which causes a callback postback. These elements reside in a callbackpanel (similar to MS's UpdatePanel but doesn't use viewstate). The repeater is bound to a datatable during initial load and repeater shows the checkboxes. Fine so far.
During the postback (a callback), I noticed that the repeater's items' count is 0 in the page_load. Therefore I can't get any checkbox values. I can see the key/checked value entries of the checkboxes in Request.Form collection.
I think I am missing something obvious but where in the life cycle can I read the repeater's items?
Or should I get them from Request.Form?
1) Try wiring up to LoadComplete. All child controls are loaded recursively, so sometimes not everything you expect to be there will be present during the Load event.
2) Make sure your repeater is initialized during or prior to Init event. If you have some code that runs to populate it, then this must be executed in Init. During the page's lifecycle, ASP.NET tries to take the posted values and apply them to the controls. If the controls are not created soon enough during the lifecycle, then they won't exist during that step to accept the posted values. This is one of the more frustrating things with dynamic pages in ASP.NET, as you have to ensure the page is reconstructed during the postback in init. So even when you see the data in the post, ASP.NET will ignore it if the controls aren't found in its collection of controls. Also, there is some magic that happens with control IDs that it uses to map the posted values into the controls. I don't remember the details of that though because it has been several weeks since I had to delve into the harry details.
Also, make sure you aren't doing something like using if(!IsPostBack) to initialize your repeater or other controls/data. Even if it's a postback, you still need the controls to exist so they can accept the posted values.
I have not used a callbackpanel though, so I am unsure of how this will muddy the waters.
I solved my problem by overriding the DataBind method on the control which contains the repeater. That prevents DataBinds on parent controls from trickling down and binding data to the repeater when it isn't ready for that. My problem was that a parent control/page performed a DataBind which trickled down to the sub-controls, including the repepater, causing it to get cleared. So you don't have to do a DataBind directly on the repeater on every postback like #AaronLS suggests:
Also, make sure you aren't doing something like using if(!IsPostBack)
to initialize your repeater or other controls/data. Even if it's a
postback, you still need the controls to exist so they can accept the
posted values.
All my RepeaterItems were stay present through postbacks even though I only databind once.
In my case, performing a DataBind on the repeater for every postback caused the form values to be reset.

I have to do two seemingly mutually exclusive things on leaving an asp:textbox. Please help me get some clairity

This project has gone from being a simple '99 Ford F-150 to the Homer.
I've got controls with a gridview with textboxes for data entry.
All the user controls on the pages are in AJAX updatepanels.
User types in a database column or budget entity or some other financial thing they want to include in the report.
The textboxes in the gridview have autopostback = true set.
overly long background info
When the user leaves the textbox, during the postback (triggered by onTextChanged) I do some validation back on the server on their entry - regexs, do they have rights to that column, is that column locked, etc. If it fails, I put a error message next to the textbox. If it passes, I wipe out any title or error that used to be next to the code.
Focus is getting lost from the postback if they're tabbing out of the box, rather than going to the next textbox in the gridview.
So to fix that I need, if their leaving the tb via the tab key, to also figure out what textbox or gridviewrow they're on, if they're not on the last row, and after the validation and labeling, put the focus on the textbox in the next row.
I can't figure out how, in ontextchanged, to find what caused me to leave the textbox, so I'm thinking use javascript onkeyup to test the key pressed and then find the next box etc, but the ontextchanged fires first and then the js never does, and also, since the control is all AJAXed, the javascript can't find the textboxes because when you enter the page everything is collapsed (the requirements people loooove to collapse and expand things), and so when it's expanded, all the 'new' textboxes are up in the viewstate stuff in the page source, and not down where javascript can see them.
The questions
So I'm wondering if I can have an onblur in the javascript that can trigger a postback where I can do my validation and such, and either 1) include the keypressed or pick it out of sender in the event or 2) followup the onblur with onkeyup and somehow figure out what textbox is next on the grid and throw focus there.
Or, is there another .NET based approach that could work for this? In terms of tearing the whole thing down and starting from scratch, I couldn't sell that to the bosses, I'm past the point of no return as far as that goes.
Does changing the one textbox value change anything else on the screen besides the error message/title associated with the textbox?
If not, my first thought would be to stop using the AutoPostBack and change to a Page Method hooked up to the onblur event. This should fix your tab issue and also reduce the back and forth between client and server.
Here's a blog post that talks about update panels and also Page Methods; The blog also includes a lot of useful posts about using javascript with .net, ajax, etc.

DropDownList always does full-page postback, the first time it fires

I have an ASP.NET page using the AJAX library. There is a dropdownlist inside an UpdatePanel, which on index changing is supposed to update a different UpdatePanel to modify a grid control.
But after the page first comes up, and you adjust the ddl, the entire page postbacks, followed by a (correct) partial postback. After this one time, every other usage of the ddl performs correctly, trigger partial postbacks.
Both the panel and the ddl are being added from code. The UP is Conditional updates and ChildrenAsTriggers = true. The dropdownlist is AutoPostBack true and has an event set up on SelectedIndexChanged.
So what is going on? I've tried adjusting every setting I can think of and still the page completely refreshes once, then works fine after that.
I believe I've solved my current woes in regards to this problem, though I'm left feeling a bit dumb by the outcome. When programmatically adding the dropdownlist, I didn't give it an ID, assuming ASP.NET would just assign it some sequential name-container mangled ID anyway. It seems this was the cause. I'm assuming that the initial postback was due to ASP.NET trying to deal with the lack of a proper ID, assigning one, and then using that afterwards for the partial postbacks.
Or maybe it's something totally different at root, but the simple fix was: add an ID to the control.

Listbox values are persisting across postbacks

I am having a listbox in ASP.net. I am populating the listbox values from another listbox in a page dynamically. During postbacks the values of output listbox are not persisted.
(while going to another page and come back to this page).
Please suggest some good answer. EnableViewstate = "true" is not working.
Are you doing anything in Page_Load that should be in a
if(!IsPostBack) {}
Initialization code in load needs to only be called when the page is first loaded, not on postbacks.
If you are going to another page and then coming back to this page, I think you need to preserve the information yourself in the Session and then restore it when you come back to the page.
The viewstate is only preserved as long as your on the same page doing postbacks.
As Lou Franco wrote
if(!IsPostBack) {}
You use this on the initial pagerequest to fill in the data. if you wish to preserve the data across pages using the session to store the values is the best bet.
preferably you fill in the data in your listbox before the SaveViewState event thats in PreInit as far as I recall.
Initialize the content of your controls in your Page's Init event (Page_Init). That way any values the user supplies are not overwritten by your defaults.
EnableViewState will just repopulate the output listbox with the values that it had when the page first rendered, since they're still the ones stored in the viewstate. The browser sends only the selected value in the postback, so there's no way for the server to know what other values you added on the client.
You can work around this by adding a hidden input to the page and populating it with the dynamic values when you update the listbox. Your page can then check that value during a postback and repopulate the list properly.
Changes made to the listbox on the client side are not persisted during a postback, you need to record that information in hidden fields and then configure the control during the page_load event to make the changes stick during the rest of the postback.

When does a DropDownList retain the value from postback at the SelectedIndexChanged Event Handler

To Clarify to all this problem absolutely does not stem from rebinding of the controls and the value does not remain the initial value after binding.
I have a DropDownList on an aspx page which is being used in multiple projects.
Along the life cycle of the page the SelectedValue is changed prior to the handling of the SelectedIndexChanged event.
In one project when the code reaches the event handler the SelectedValue is back to what was posted from the client, while in the other the new SelectedValue is present.
Viewstate is on in both cases, the control is not being rebound and follows the exact same flow from all that I can gather.
The control is not being initialized again, I checked this thoroughly and does not retain the initial value but rather the value set in the code.
I actually need the posted value at the point of the event handler like is happening in the first project but do not understand why it would be changing back to the posted value and how to replicate this behavior in the second project.
I will be happy to clarify further if any of this is unclear.
Maybe some initialization is performed twice in the on_load event because you dont check the page is posted back using IsPostBack in a test ?
It exactly happens to one of my colleague ten minutes ago :-)
Many people wrongly believe that DropDownLists must have ViewState on to be able retain selected value. I almost never have EnableViewState set to true on DropDownLists because they work fine in a form with the posted values. (And setting it to true on a DataBinding control will cause a long viewstate)
The posted value (selected item in the dropdown) is loaded from the post-parameters after OnInit in the page so if you bind the data to the dropdown in OnInit it will work fine.
If you bind in OnLoad, the selected Value will be overridden.
Perhaps you are databinding in the wrong event so that the selected value gets overridden by a DataBind-call on the dropdown?
I usually see this behavior when I've forgotten to check IsPostback somewhere. The page will load all of the original data before going to the SelectedIndexChanged event handler.

Resources