Sharepoint "edit page" keeps loading due to certain webpart - asp.net

I have a sharepoint test page. I inserted my webpart earlier before my development, but after a period of time now I find that when I click "edit page", the "loading" tag will run forever and I cannot edit my page.
Then I tried to type "?Contents=1" after my page url, delete the webpart and re-add it. When I tried to save my changes, the "saving" tag also runs forever.
Such issue only happens to my webpart. I tried to use other webparts and they works perfectly. Any one got some idea?

In your custom webpart code, you can understand if the page is in edit mode by the below code. Debug the code and try to understand the reasing of waiting.
By this way, you can modify your webpart for edit mode.
protected override void OnLoad(System.EventArgs e)
{
if (this.IsInEditMode)
{
}
}
private bool IsInEditMode
{
get
{
SPWebPartManager currentWebPartManager = (SPWebPartManager)WebPartManager.GetCurrentWebPartManager(this.Page);
return (((currentWebPartManager != null) && !base.IsStandalone) && currentWebPartManager.GetDisplayMode().AllowPageDesign);
}
}

OK,I find the reason. Since my webpart has an textbox validator and by default the textbox is hidden, when I click "edit page", the validator will be fired and prevent the editing. I put the following code in my page_load JavaScript and the issue is solved.
$(function () {
var rfv = document.getElementById("<%=rfvName.ClientID%>");
ValidatorEnable(rfv, false);
});

Related

Display ReportViewer results on Load - ServerReport.Refresh() doesn't do anything

I have a ReportViewer control on my webpage. It loads properly and when I click on the "View Report" button, the results are properly displayed.
But now I want it to display the results when the page loads and not ask the user to click on the "View Report" button.
I see everywhere that I must use the ServerReport.Refresh() method, but it doesn't seem to do anything. I subscribed to the ReportRefresh event, it's not even fired.
The control is on a "regular" page, nothing else on it, no UpdatePanel.
I added a button that also executes ServerReport.Refresh() but it doesn't work either, nothing happens.
I tried to enable/disable most options that seem to relate to the issue (ShowRefreshButton, AsyncRendering...) and I've set all the parameters.
I also tried to put the initialization code in the Page_Init() method, without success.
The report won't load without clicking on the "View Report" button.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Sets credentials, URL & Path
ReportHelper.InitializeReportViewer(rptViewer);
rptViewer.ProcessingMode = ProcessingMode.Remote;
rptViewer.ShowReportBody = true;
rptViewer.ReportRefresh += rptViewer_ReportRefresh;
var v = rptViewer.ServerReport.GetParameters().Select(p => new ReportParameter(p.Name, p.Values.ToArray()));
rptViewer.ServerReport.SetParameters(v);
rptViewer.AsyncRendering = false;
rptViewer.ServerReport.Refresh();
}
}
I'm still looking for a better answer but until then, I hide the parameters panel (and might even hide the collapsed bar through CSS) and simulate a click on the button.
It's not ideal, but it works.
In the code behind :
rptViewer.PromptAreaCollapsed = true;
In the ASPX script header :
$(document).ready(function () {
var btnSubmit = $("#<%=rptViewer.ClientID%> :submit");
btnSubmit.trigger("click");
});

Maintaining TabContainer active tab after postback from within the tabs (with AutoPostBack='false')

I have an AjaxToolkit TabContainer control with a number TabPanels. Each TabPanel has a different UserControl in it to display some information. Some of these UserControls have either a LinkButton or a GridView with a command button in them. The TabContainer has AutoPostBack="false" and this is how I would like to keep it.
When you click on the LinkButton or command button in the GridView the expected events fire and the code runs. But when the page is returned the initial tab is selected again (and not the tab the user was previously viewing).
So my question is: Is there a way to maintain the selected tab when some child control causes a postback?
Some constraints:
I do not way to turn AutoPostBack on. This means the linked solution for this question question is no good in this case.
The UserControls are not always used in a TabContainer/TabPanel so the solution can not assume that this is the case.
The solution needs to be fairly robust and straightforward as there could be different devs working on this code.
I solved this problem by creating my own control that inherits from TabContainer, then overriding LoadClientState() like this:
protected override void LoadClientState(string clientState)
{
base.LoadClientState(clientState);
// If post back was caused by control on a tab, make that tab the active one
if (!string.IsNullOrEmpty(this.Page.Request.Params["__EVENTTARGET"]))
{
foreach (string ctlName in this.Page.Request.Params["__EVENTTARGET"].Split('$'))
{
if (this.FindControl(ctlName) is TabPanel && this.Tabs.Contains(this.FindControl(ctlName) as TabPanel))
{
this.ActiveTab = (this.FindControl(ctlName) as TabPanel);
break;
}
}
}
}
This finds the TabPanel on which the control causing the postback resides, then makes that the active panel.
I got this from another forum. You set this in the pageload. I don't know if that would help with them being set to AutoPostBack=false, but if you haven't given up on it yet, I hope this helps
if (ViewState("ActiveTabIdx") != null)
{
activeTabIndex = Convert.ToInt32(ViewState("ActiveTabIdx"))
if (activeTabIndex != null)
{
TabContainer1.ActiveTabIndex = activeTabIndex;
}
}
you need to add ActiveTabChanged event for tab container and you can keep active tab index in view state, and on page load just check if it is not null then set it as Active tab index.
protected void TabContainer1_ActiveTabChanged(object sender, EventArgs e)
{
ViewState["ActiveTabIndex"] = TabContainer1.ActiveTabIndex;
}
PageOnLoad Event code
if (!(ViewState["ActiveTabIndex"] == null) )
{
TabContainer1.ActiveTabIndex = (int)ViewState["ActiveTabIndex"];
}
Make sure to add following attributes in TabContainer tag
AutoPostBack="true" OnActiveTabChanged="TabContainer1_ActiveTabChanged"

Loading of controls outside of Page_Load is a no-no?

My apologies in advance for posting such a lengthy question. Believe it or not, what you see here actually represents a fairly condensed version of the problem/code at hand. And while I would appreciate any pointers on a better or different approach, I would also very much like to get the bottom of this so that I can sleep at night :)
I came across a requirement to pass confirmation messages between distinct aspx pages. I opted against using a query string variable since query string values "are" sticky (i.e. they persist on all subsequent postbacks) and I didn't want to deal with adding a bunch of conditional logic around this.
Anyway, I came up with a very simple class that uses Session to associate notifications with specific URLs. I then hooked my master page Page_Load event to query this class for any notifications that should be displayed for the current URL. If it finds any, it dynamically loads a NotificationMessage user control and displays the message content.
Everything works as expected when trying to pass Notifications between different aspx pages. Predictably, things don't work when a content page attempts to add a notification to itself (i.e. "The data you entered is not valid, try again"). The reason is pretty clear: by the time a content page adds a Notification for itself, the Page_Load event of the master page has already fired, so it's too late in the page lifecycle to do any good. The relevant code is pasted below.
public class MyMasterPage:MasterPage{
protected void Page_Load(object sender, EventArgs e)
{
LoadNotifications(this.Request.Url.ToString());
}
private void LoadNotifications(string url)
{
//look for a notification
Notification? notification = NotificationManager.Instance.RetrieveNotification(url);
//there are no notifications, nothing to see here
if (!notification.HasValue)
{
return;
}
//there is a Notification for this url, so load it into a user control
NotificationMessage notificationMessageControl = (NotificationMessage)LoadControl("~/App_UserControls/NotificationMessage.ascx");
notificationMessageControl.ID = "notificationMessage";
notificationMessageControl.Notification = notification;
notificationMessageControl.Visible = true;
//find the placeholder on the master page
PlaceHolder placeHolder = (PlaceHolder)PageUtils.FindControlRecursive(this, "NotificationPlaceholder");
if (placeHolder == null)
{
throw new ApplicationException("NotificationPlaceholder control not found.");
}
//insert into control
placeHolder.Controls.Add(notificationMessageControl);
placeHolder.Visible = true;
//remove the notification so it doesn't show up next time
NotificationManager.Instance.RemoveNotification(url);
}
}
Given the lifecycles issued alluded to above, I modified the NotificationManager class so that it raises an event whenever a notification has been added for the current page. The master page intercepts that event, and if the Page_Load has already fired, it kicks off the LoadNotifications method all over again.
//bind the event on the page constructor
public MyMasterPage()
{
NotificationManager.Instance.NotificationAdded += this.NotificationAdded;
}
private void NotificationAdded(string forUrl)
{
if (_pageLoaded){
LoadNotifications(forUrl);
}
}
Unfortunately, this doesn't work. I have stepped through this code numerous times, and despite the fact that the master page loads the NotificationMessage UserControl and adds it to the appropriate placeholder without incident, the final aspx HTML never includes the markup for that UserControl. I've put breakpoints inside the Page_Load of the UserControl and verified that they are indeed being hit during execution.
If I dynamically load the UserControl from inside the content page and bypass the Master page altogether, it renders without a hitch:
public partial class MyContentPage:Page
{
public void DoSomethingCool(object sender, EventArgs e)
{
if (MyServiceLayer.Save(foo)==false){
Notification notification = new Notification(NotificationType.Error, "We’re sorry, your document was not saved.");
NotificationMessage notificationMessage = (NotificationMessage)LoadControl("~/App_UserControls/NotificationMessage.ascx");
notificationMessage.Notification = notification;
notificationMessage.Visible = true;
PlaceHolder holder = (PlaceHolder)PageUtils.FindControlRecursive(this, "NotificationPlaceholder");
holder.Controls.Add(notificationMessage);
}
}
}
For the record, I stripped out the dynamic loading of the UserControl, opting instead for a a static declaration in the master page markup and a code based toggle of the control's Visible property; still no dice!
If someone could shed some light on this conundrum, I would be much obliged.
I've tried this sort of thing before and I was never fully comfortable with it. What I did instead, was put my ASCX on every page (or on the masterpage), and let the ASCX control its state rather than letting the ASPX control my ASCX.
I'm not sure this will help for your situation, though.
It seems like you want your information to show up after your control events fire. You might consider letting those messages aggregate until all control events have fired and then pull out all of the messages from your NotificationManager in OnPreRender, rather than Page_Load. That way you can get rid of the events (like NotificationAdded), etc that are probably complicating matters.
Not 100% what the problem is, though. It sometimes helps to know that the MasterPage is actually a control on the Page, rather than the other way around like you would think. It is going to be subject to the limitations any control would have on a Page.
HTH, Anderson

ASP.NET User control, databinding DataTable

I got a user control containing a form. On a page that includes the user control, I need to populate the form in the user control, when the user pushes a button.
Heres how I've done it, and it doesn't work:
User Control:
public partial class editUC : System.Web.UI.UserControl
{
public DataTable dataTable { set { UpdateForm(value); } }
protected void Page_Load(object sender, EventArgs e) { }
private void UpdateForm(DataTable dt) { txtControl.Text = dt.Rows..... ... }
}
Where UpdateForm binds different text boxes.
And the page containing the UC, when a button has been clicked:
EditUserControl.dataTable = dt;
Clicking the button, nothing happens. What am I missing here?
Thanks in advance.
UPDATE:
I got a bit closer. It's because I'm using a jQuery dialog for the user control. It works if I remove the jQuery.
This is how I create the dialog:
$(document).ready(function() {
var dlg = $('.editFormDialog').dialog({
autoOpen: false,
height: 650,
width: 550,
modal: true,
bgiframe: true,
title: 'Rediger',
open: function(type, data) {
$(this).parent().appendTo("form");
}
});
dlg.parent().appendTo("form");
$('#btnEdit').live('click', function() {
$('.editFormDialog').css('visibility', 'visible');
$('.editFormDialog').dialog('open');
});
});
I am appending it to the form, but it doesn't work. Any ideas?
2nd update:
It works if I remove the update panels from the page. Any ideas? :-)
are you using Caching on the control? If the control's contents is cached using the ASP.NET control caching mechanism, then there will be no change on the control's text.
Can you add a breakpoint inside the private void UpdateForm(DataTable dt) to make sure this function gets called when you click on your button?
Depending on what the user control contains you might need to do a EditUserControl.DataBind();
If you are sending javascript code (jquery) as part of your update panel async postback, it's important to remember that javascript will not be evaluated by the browser. You need to find another method to run that code after your async postback.
Also, when you do an async postback on an UpdatePanel control, all the DOM elements in that control get trashed and replaced by new elements. The jQuery elements have to be re-created again.
User controls aren't meant to be as complex as this. They're meant to be a simple matter of pulling out some reusable portion of markup, then maybe adding a few properties, methods and events. They're not meant to do data binding. You really should rewrite tihs control as a composite server control.
That said, you'd probably get the most traction out of this by acting like it's a real server control. Binding to data would occur in the DataBinding event. In that event, you should set the DataSource property of the grid, then call DataBind on the grid.

Why are textboxes in my page getting focus on pageload?

I have a page with textboxes and buttons. When the page loads, often times, focus is in one of the textboxes and I don't want this to happen. However, I don't want to use something like setfocus in the page load event because then when buttons are clicked the page will jump. How do prevent the textboxes or any controls for that matter of getting focus on page load?
strange. by default, the page will not focus on any form input unless you set focus on it.
I think you have to cancel all focus by Setfocus on page.
protected void Page_Load(object sender, EventArgs e)
{
// make sure its not a postback
if (!IsPostBack)
{
// your code
InitForm();
InitBlaBlaBla();
SetFocusOnThis();
SetFocusOnThat();
// cancel all focus
Focus();
}
else
{
// this is a postback,
// set focus on control which make post back
Control control = null;
if (!string.IsNullOrEmpty(Page.Request.Params[postEventSourceID]))
{
control = Page.FindControl(Page.Request.Params[postEventSourceID]);
}
else
{
// if postEventSourceID is null, its a button
// find it by iterating all controls
foreach (string ctl in Page.Request.Form)
{
Control c = Page.FindControl(ctl);
if (c is System.Web.UI.WebControls.Button)
{
control = c;
break;
}
}
}
// finally
control.Focus();
}
}
basically what I want to do is when
the page loads as the result of
redirecting from another page, don't
set the focus in any textboxes, just
load the page normally, but if the
page loads as a result of clicking a
control on the page, keep the focus
on/near that control.
To accomplish this you have to test for post back. If you detect the page has been posted back, you can set focus to the control, as you intend to. Otherwise, the page is not beeing posted back (GET), so you can avoid the focus on the control.
As far as I know, by default, ASP.NET Webforms don't set the focus on any of textboxes. Are you sure you don't have some code-behind method setting the focus on the textbox?
It turns out that freetextbox controls exhibit this behavior on IE7 and IE6. It is a bug they are investigating.

Resources