Tab Control and GridView

  • Thread starter Thread starter Peter
  • Start date Start date
P

Peter

I have a Tab control with several tabs, on one of the tabs I have a
GridView, which takes long time to populate when user opens the webpage, so
I want to populate the GridView only when user clicks on the tab with the
GridView, but I don't want to use a Postback on all of the tabs, because
Postback takes too long, a user can click on several tabs before one
postback completes.

Does anyone have an idea how to accomplish this, populate the GridView only
when the user clicks on the Tab?

Thank You


Peter
 
Hello peter,

Based on my understanding, you want to update GridView when the user clicks
the related TabPanel, instead of loading GridView in Page_Load. If I have
misunderstood you, please feel free to let me know.

1. Firstly, please build an UpdatePanel in TabPanel. We can make use of
OnClientActiveTabChanged event to check if active TabPanel is the one that
contains GridView control. If so, we can update the UpdatePanel with
GridView control via JavaScript.

Please check the following sample. There is a Label contorl in TabPanel2.
To simplify the problem, I assume this Label control is your GridView. In
the first Page_Load, it will not be rendered. Untill you click TabPanel2,
it will generate an asynchronous request and update UpdatePanel1. Let's
make an UpdateProgress to check the partial updating clearly.

JavaScript:

<script type="text/javascript">
function onTabChanged() {
var index = $find("TabContainer1").get_activeTabIndex();
if (index == 1)

Sys.WebForms.PageRequestManager.getInstance()._doPostBack('<%=UpdatePanel1.U
niqueID %>', '<%=UpdatePanel1.UniqueID %>')

}
</script>

HTML code:

<body>
<form id="form1" runat="server">
<ajaxToolkit:ToolkitScriptManager runat="Server"
EnablePartialRendering="true" ID="ScriptManager1" />
<asp:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>
loading...
</ProgressTemplate>
</asp:UpdateProgress>


<ajaxToolkit:TabContainer runat="server" ID="TabContainer1"
OnClientActiveTabChanged="onTabChanged">
<ajaxToolkit:TabPanel runat="server" ID="TabPanel1"
HeaderText="TabPanel1">
<ContentTemplate>
<%=DateTime.Now %>
</ContentTemplate>
</ajaxToolkit:TabPanel>
<ajaxToolkit:TabPanel runat="server" ID="TabPanel2"
HeaderText="TabPanel2">
<ContentTemplate>
<asp:UpdatePanel ID="UpdatePanel1" runat="server"
OnLoad="UpdatePanel1_Load">
<ContentTemplate>
<asp:Label ID="Label1" runat="server"
Text=""></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</ajaxToolkit:TabPanel>
<ajaxToolkit:TabPanel runat="server" ID="TabPanel3"
HeaderText="TabPanel3">
<ContentTemplate>
<%=DateTime.Now %>
</ContentTemplate>
</ajaxToolkit:TabPanel>
</ajaxToolkit:TabContainer>
</form>
</body>



Code Behind:

protected void UpdatePanel1_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
System.Threading.Thread.Sleep(3000);
Label1.Text = DateTime.Now.ToString();
}
}

2. However, there is a problem in this sample. When you click the
TabPanel2, it will update the GridView. During the 3-sec updating process,
if you click the TabPanel2 again, it will generate another request. In
Asp.Net Ajax, the new asynchronous request will abort the old one. In case
that the user clicks TabPanel2 continuously when UpdatePanel is updating,
it will cancel the old request and launch the new one continuously. So, we
had better enforce the existing request in this case.
Please add the following JavaScript code to the above HTML code at all if
you want.(Please put it after </body> tag.)

<script type="text/javascript" language="javascript">
var lastPostBackButtonId = null;
var btnPrecedenceId = "<%= this.UpdatePanel1.ClientID %>";

Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(
function(sender, e) {

var prm = Sys.WebForms.PageRequestManager.getInstance();
if (prm.get_isInAsyncPostBack()) {
if (lastPostBackButtonId == btnPrecedenceId) {
e.set_cancel(true);
return;
}
}

lastPostBackButtonId = e.get_postBackElement().id;
});
</script>


3. Hope the above solution is what you want. However, in this way,
whenever the user clicks TabPanel, it will generate a request and update. I
think it had better update the GridView control only if TabPanel is first
clicked. You can set a toggle variable on client to achieve it.
You can modify the existing code with the following code:

<script type="text/javascript" language="javascript">
var updateCounter = 0;
function onTabChanged() {
var index = $find("TabContainer1").get_activeTabIndex();
if (index == 1 && updateCounter==0) {

Sys.WebForms.PageRequestManager.getInstance()._doPostBack('<%=UpdatePanel1.U
niqueID %>', '<%=UpdatePanel1.UniqueID %>')
updateCounter = 1;
}

}
</script>

Furthermore, you can set an "update" button in TabPanel2 so that the
users can update GridView whenever they want.



AjaxControlToolkit is following Microsoft Public License (Ms-PL), which is
out of the support boundaries of our managed newsgroups. Please post it to
http://forums.asp.net/1022.aspx if you'd like. It is not managed, but this
forum will provide support for AjaxControlToolkit professionally.
AjaxControlToolkit License:
http://www.codeplex.com/AjaxControlToolkit/license
MSDN Newsgroup Support Boundary:
http://blogs.msdn.com/msdnts/archive/2006/11/08/msdn-service-introduction.as
px


Sincerely,

Vince Xu

Microsoft Online Support

£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

MSDN Managed Newsgroup support offering is for non-urgent issues where an
initial response from the community or a Microsoft Support Engineer within
2 business day is acceptable. Please note that each follow up response may
take approximately 2 business days as the support professional working with
you may need further investigation to reach the most efficient resolution.
The offering is not appropriate for situations that require urgent,
real-time or phone-based interactions. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx

£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½£½
 
Thank you very much this is what I needed!!!

I just have one question, I have a cancel button on my page how do I prevent
from the "loading..." template to appear when I click on the Cancel button ?

<ProgressTemplate>
loading...
</ProgressTemplate>
 
Hello,

You can abort the existing asynchronous request by using method
"abortPostBack".

<input type="button" value="Abort"
onclick="Sys.WebForms.PageRequestManager.getInstance().abortPostBack();" />

Hope it helps.
 
Sorry I did not explain.

I have a Cancel button on the web page which redirects to a different web
page by using Response.Redirect. When I click the cancel button the
Loading... appears before the page gets redirected. How can I prevent the
"Loading.." from showing up when a user clicks on the Cancel button?
 
Hello,

Based on my understanding, you don't want to show UpdateProgress when you
click the Cancel Button.

You can put the Cancel Button into another UpdatePanel(UpdatePanel2), and
set property "AssociatedUpdatePanelID" of UpdateProgress to
"UpdatePanel1"(which contains GridView in TabPanel). Then UpdateProgress
will be shown only if you click the controls in UpdatePanel1.

If the Cancel Button is in the GridView so that you can't split them into
two different UpdatePanel controls, I suggest you use HyperLink to navigate
to another page directly, instead of using Response.Redirect.


Sincerely,

Vince Xu

Microsoft Online Support
 
The Cancel Button is not in the GridView.

After I set the property of AssociatedUpdatePanelID to "UpdatePanel1" the
"Loading..." never appears at all, when I click on the Tab or after I click
on the cancel button

I've added
 
Hello Peter,

Is "Loading" shown on the page if you don't set AssociatedUpdatePanelID?

I suggest you try to define "AssociatedUpdatePanelID" in Page_Load event.
I hope the following sample code can help you.
In this sample, I set the property "AssociatedUpdatePanelID" in Page_Load
event and set the update mode of UpdatePanel1 to "Conditional". In
addition, I used UpdatePanel2 to wrap the Cancel button.

<script type="text/javascript" language="javascript">
//whatever script I listed you used
</script>

<body>
<form id="form1" runat="server">
<ajaxToolkit:ToolkitScriptManager runat="Server"
EnablePartialRendering="true" ID="ScriptManager1" />
<asp:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>
loading...
</ProgressTemplate>
</asp:UpdateProgress>
<ajaxToolkit:TabContainer runat="server" ID="TabContainer1"
OnClientActiveTabChanged="onTabChanged">
<ajaxToolkit:TabPanel runat="server" ID="TabPanel1"
HeaderText="TabPanel1">
<ContentTemplate>
<%=DateTime.Now %>
</ContentTemplate>
</ajaxToolkit:TabPanel>
<ajaxToolkit:TabPanel runat="server" ID="TabPanel2"
HeaderText="TabPanel2">
<ContentTemplate>
<asp:UpdatePanel ID="UpdatePanel1" runat="server"
OnLoad="UpdatePanel1_Load" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="Label1" runat="server"
Text=""></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</ajaxToolkit:TabPanel>
<ajaxToolkit:TabPanel runat="server" ID="TabPanel3"
HeaderText="TabPanel3">
<ContentTemplate>
<%=DateTime.Now %>
</ContentTemplate>
</ajaxToolkit:TabPanel>
</ajaxToolkit:TabContainer>

<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<asp:Button ID="CancelButton" runat="server"
Text="CancelButton" OnClick="CancelButton_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>

Code behind:

protected void Page_Load(object sender, EventArgs e)
{
UpdateProgress1.AssociatedUpdatePanelID =
TabPanel2.FindControl("UpdatePanel1").UniqueID;
}

protected void CancelButton_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(2000);
Response.Redirect("a.aspx");
}

protected void UpdatePanel1_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
System.Threading.Thread.Sleep(3000);
Label1.Text = DateTime.Now.ToString();
}
}


If it can't help you out, please post your code.

Sincerely,

Vince Xu

Microsoft Online Support
 
Yes the "Loading..." shows on the page if I don't set
AssociatedUpdatePanelID.

Thanks for your help, but putting AssociatedUpdatePanelID in the Page_Load
event did the same thing as assigning it on the .ascx page.
the "Loading..." does not show up at all.
 
Hello Peter,

Could you please post your code if you don't mind? Or, you can send the
code files to me. ([email protected])

I doubt that UpdateProgress didn't follow the correct associated
UpdatePanelID.
Can you assist me to check your source code in the browser? (view
sourcecode in browser)
There is some codes looks like :
"$create(Sys.UI._UpdateProgress,
{"associatedUpdatePanelId":"XXX_XXX_UpdatePanel1","displayAfter":500,"dynami
cLayout":true}, null, null, $get("UpdateProgress1"));"

Assuming that is "XXX_XXX_UpdatePanel1" here. Is it equal to the clientID
of UpdatePanel1?
(In TabContainer div, there is a div whose id is like
"XXX_XXX_UpdatePanel1". This is the clientID of UpdatePanel1.)

Sincerely,

Vince Xu

Microsoft Online Support
 
Hello Peter,

Actually, we haven't to use UpdateProgress to show "loading" message. We
can make it manually. I think it will figure out and simplify the problem
by using the approach as below.

1. We can build a span with "loading" message. Please put the following
code into the page.
<span id="loadingMessage" style="display:none;">loading...</span>

2. Before doing postback for UpdatePanel1, we can display it.

<script type="text/javascript">

function onTabChanged() {
var index = $find("TabContainer1").get_activeTabIndex();
if (index == 1) {
$get('loadingMessage').style.display = "block"; // Put this
code before "_doPostBack" whatever script I listed you used.

Sys.WebForms.PageRequestManager.getInstance()._doPostBack('<%=UpdatePanel1.U
niqueID %>', '<%=UpdatePanel1.UniqueID %>')
}

}


</script>
3. After update is completed, we can set it back.

<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
function(sender, e) {
$get('loadingMessage').style.display = "none";

});
</script>


In this way, "loading" will be displayed only if you click the TabPanel2.

Sincerely,

Vince Xu

Microsoft Online Support
 
Back
Top