AJAX Partial page update problem when displaying a control - c#

I have an interesting problem when using partial page update in asp.net with scriptmanager and a update panel.
My scenario looks like this: I'm using the tab control from the ajax toolkit. I also implemented this control using lazy loading, so that when the page is loaded only the current tab gets loaded all the other tabs don't get rendered, because Im using an UpdatePanel (on a .ascx control) on each of these tabs and when a tab gets selected the updatepanel makes a async postback to load the content for a selected tab.
On one of my tabs Im using a combobox control from obout.com, and it doesn't work.
Now I know why it doesn't work. It doesn't work because the control is shown via a partial page refresh, but to correctly display the control it has to do some "magic" that is - register some .css and .js includes on the page (in the head I guess)....but because I load this control via async page refresh...it can't do these stuff.
What kind of workarround do you suggest?
Thanks!

Assuming you have done partial ajax updates in asp.net before, then you simply need to register a client block with the ScriptManager for when the partial update is triggered.
Without knowing your problem space, it's difficult to paste specific code for you, so instead I'll just suggest you read this and then ask more questions if you have them...
http://msdn.microsoft.com/en-us/library/system.web.ui.scriptmanager.registerclientscriptblock.aspx
BTW, if you're dynamically creating the controls as well as partially updating them, then you will also need to be very careful of your viewstate. This is a can of worms, so hopefully you are not and won't have to worry about it.

As I suspected you have to manually register the needed scripts for ajax controls to work in such a manner.
For example here is the solution for telerik controls:
http://www.telerik.com/help/aspnet-ajax/troubleshooting.html
Here is a solution using devexpress controls:
protected void Page_Load(object sender, EventArgs e)
{
DevExpress.Web.ASPxClasses.ASPxWebControl.RegisterBaseScript(this);
}
I didn't found a solution for obout.com controls.

Related

Manually trigger Update Panel

I have an UpdatePanel in the page.
Inside this UpdatePanel, I have a control which has a button.
Is it possible to Manually add a postback trigger for this button (which is inside the user control) in the code behind?
Here's the sample code
//Page
<UpdatePanel>
<uc1:UserControl />
</UpdatePanel>
//UserControl
<textbox></textbox>
<asp:button></asp:Button>
As I understand, you want to register the button in your user control as a PostbackTrigger of an UpdatePanel in your ASPX page which contains your user control.
I have managed to write a simple web application that replicates this scenario and without further information I cannot see where you're going wrong or what the error that you're getting is, if any. It would help if you expanded on your original question e.g. by providing relevant snippets of your code. I'll try my best...
From within the user control you can register the button as a post back trigger of the update panel with the following code:
public void RegisterPostbackTrigger(UpdatePanel updatePanel)
{
PostBackTrigger buttonTrigger = new PostBackTrigger();
buttonTrigger.ControlID = TestButton.ClientID;
updatePanel.Triggers.Add(buttonTrigger);
}
You will then have to call the RegisterPostbackTrigger from within you page's code behind passing in you UpdatePanel's reference as an argument. MyControl refers to the UserControl
MyControl.RegisterPostbackTrigger(MainUpdatePanel);
An alternative way of doing this, which may be relevant to your particular issue is to access the ScriptManager directly and use its RegisterPostBackControl method passing in your button as the parameter. Here's the a link!
Can't really help you anymore without more information!
Good luck!

Why can't I see variables nor viewstates after partial postbacks in a webpart?

Something very odd is happening here.
I have a custom WebPart within Sharepoint which sends forms to Excel and by E-Mail. I'm using Asp.NET 3.5, Ajax, jQuery.
Inside OnInit() I'm connecting to TeamFoundation Server, opening an excel template, initializing jQuery, and loading up the css.
CreateChildControls() adds the controls to panels and such, and creates an empty literal i'm calling "litScript".
Inside PreRender(), I'm updating values based on partial (or not) postbacks and such. I also assign a value to litScript, which composes some layout rounding effect, a jQuery-based tab effect, and mouse-following progress icon.
I have many tabs with buttons which, upon clicked, process some stuff.
Upon assigning a random text "I'm here!" to a label inside some button click event, it reloads perfectly.
cc.GetTextControl("lblTeste").Text = myForm.PostbackMessage;
(cc.GetTextControl just returns my control).
However, by using my literal and writing
cc.GetTextControl("litScript").Text = "<somejavascript>"+myForm.PostbackMessage+"</somejavascript>";
I don't get anything.
When I do a full postback, everything loads correctly though.
What is happening?
Had something to do with javascripts not changing. I just added a RegisterClientScriptBlock and everything went fine.

Allow .ASPX page to display before .ASCX control finishes loading?

I have an ASP.NET page with one control (.ascx) on it. The page (.aspx) onload assigns some text to a couple labels and passes a product ID to the .ascx control. The .ascx control, onload, takes that product ID from the .aspx page and hits the database several times, does several calculations, etc - basically takes a long time to load.
So when I'm clicking a link to this .aspx page, it is taking 7-10 seconds for the page to load. I've narrowed it down to the calculations on the .ascx control being the culprit and I've optimized the code as much as I can ... but it's still taking too long.
Is there a way to load the .aspx page BEFORE the control loads? (Maybe display a "Loading..." animation? Like used in an UpdateProgress?)
You could do this with an UpdatePanel. It will take a little trickery, but try something like this:
1) Put the UserControl in an UpdatePanel.
2) Put a public property on your usercontrol like IsEnabled that it will use to conditionally do nothing or render a "please wait." Set it false from your main page.
3) Add some code in OnInit to your main page:
if (MyScriptManager.IsInAsyncPostback) {
MyUserControl.IsEnabled=true;
}
4) Add a client script along these lines:
finished=false;
Sys.WebForms.PageRequestManager.pageLoaded(function(sender,args) {
if (!finished) {
finished=true;
__doPostBack('','');
// you can include the uniqueID of your updatepanel as the first arg
// otherwise it will refresh all update panels
}
});
or with jquery..
finished=false;
$(document).ready(function() {
if (!finished) {...
}
});
What this should do is cause an async postback to be initiated immediately after the page is done loading, which will in turn cause the update panel to be refreshed. Since you set it to be enabled when it's in an async postback, it will render itself the 2nd time.
The only possible way to achieve this is by setting it up as a separate HTTP resource. At the moment .NET is integrating the control into the page so that it is waiting unti it has everything it needs to respond.
You could do this a multitude of different ways:
Web Service that gets called via javascript
Seperate page which contains the control (and is hosted within an iFrame to appear to be on the same page)
The best way to do this would be to use an iFrame (or something similar) which will instruct the browser to request the control after the main page has been sent).
Personally, I would never use an iFrame to load content on a page - that's more like a hack than anything and plus, iframe == "bad".
But they are right, you won't be able to do anything like what you're looking for.
If the user control DOES NOT have any web controls that cause a postback (or have any form controls that you need to access during a postback), then I would use AJAX to request the data on the server after the page has already loaded and use javascript to display the content on the page.

Remove statically added controls at runtime

The Scenario: I have an asp.net website where I show a div popup on page load for taking a few user details. When a user inputs the details, or closes the popup, I set up a flag cookie so that the popup is not displayed again for the user. The div is in the MasterPage so that it is displayed no matter on which page a user lands first time. The div contains an UpdatePanel which has all the controls required for taking the details. This whole functionality is working fine.
The Problem: Now this div popup is not showing(by setting display:none) on subsequent postbacks(which I want), but the html markup is still loading with the page unnecessarily adding to the page size. What I would idealy want to do is: Check if flag cookie is set. If no, show the popup, else remove the popup's markup from the page.
Now since the div is not a server control, I cannot possibly remove it and the all the controls inside it. So, I thought of removing the UpdatePanel from the page:
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Cookies["flag"] != null)
{
if (Page.Controls.Contains(updpnl_contact))
{
Page.Controls.Remove(updpnl_contact);
updpnl_contact.Dispose();
}
}
}
But I guess this tends to work with dynamically added controls only, and since the control is added at Design Time, it is not being removed.
Is there any way I can achieve this?
If you add a runat="server" attribute to your <div> element, it will be available in the code-behind. You'll need an id on it as well. Then you can just toggle the Visible property. If this property is false, the control won't be rendered to the client (i.e. no HTML markup).
What you're trying to do is not at all the usual workflow. I tend to think that it will not work as it would mess up control tree, maybe even corrupt the viewstate and so on.
As a possible solution, you can put it's visibility to hidden in the code behind. This, in the contrary to the usual 'gut feeling', doesn't work like the css propery 'display:none' for example - instead the control will not even be rendered into the page when it's not visible. This may be the workaround for you.
Happy coding.
A more efficient approach would be to create the panel as a UserControl and load it dynamically in codebehind when it's needed, then add it to your page. E.g, in code:
MyPopupControl popup = (MyPopupControl)Page.LoadControl("/path/to/usercontrol.ascx");
PopupPanel.Controls.Add(popup);
Where PopupPanel is an empty <asp:Panel>. Then, not even the markup will need to be loaded/processed except when its needed.
There is no reason that all the code you use to display and process this panel couldn't also be in the usercontrol, isolating it from the master page.
Can you build the panel dynamically, based on the cookie setting?

How can I pass data from an aspx page to an ascx modal popup?

I'm fairly new to ASP.NET and trying to learn how things are done. I come from a C# background so the code-behind portion is easy, but thinking like a web developer is unfamiliar.
I have an aspx page that contains a grid of checkboxes. I have a button that is coded via a Button_Click event to collect a list of which rows are checked and create a session variable out of that list. The same button is referenced (via TargetControlID) by my ascx page's ModalPopupExtender which controls the panel on the ascx page.
When the button is clicked, the modal popup opens but the Button_Click event is never fired, so the modal doesn't get its session data.
Since the two pages are separate, I can't call the ModalPopupExtender from the aspx.cs code, I can't reach the list of checkboxes from the ascx.cs code, and I don't see a way to populate my session variable and then programmatically activate some other hidden button or control which will then open my modal popup.
Any thoughts?
All a usercontrol(.ascx) file is is a set of controls that you have grouped together to provide some reusable functionality. The controls defined in it are still added to the page's control collection (.aspx) durring the page lifecylce. The ModalPopupExtender uses javascript and dhtml to show and hide the controls in the usercontrol client-side. What you are seeing is that the click event is being handled client-side by the ModalPoupExtender and it is canceling the post-back to the server. This is the default behavior by design. You certainly can access the page's control collection from the code-behind of your usercontrol though because it is all part of the same control tree. Just use the FindControl(xxx) method of any control to search for the child of it you need.
After some research following DancesWithBamboo's answer, I figured out how to make it work.
An example reference to my ascx page within my aspx page:
<uc1:ChildPage ID="MyModalPage" runat="server" />
The aspx code-behind to grab and open the ModalPopupExtender (named modalPopup) would look like this:
AjaxControlToolkit.ModalPopupExtender mpe =
(AjaxControlToolkit.ModalPopupExtender)
MyModalPage.FindControl("modalPopup");
mpe.Show();
Sorry, but I'm confused. You can't call an ascx directly, so...
Is your modal code that you are calling from within the same page, like a hidden panel, etc;
Or is it another aspx page that you are calling on a click event?

Categories